我正在尝试在为有关用户的所有可能数据提供 1 个巨大的表之间做出决定,其中很多不会适用于每个用户,然后为用户可以拥有多个实例的数据创建一个单独的表(例如,以前的工作)与将每个用户的数据分布在多个表之间。
第一种方式更加精简,但我觉得它会使用大量不必要的开销,而第二种方式的结果更容易使用,但会导致大量额外的数据库查询。
我正在尝试在为有关用户的所有可能数据提供 1 个巨大的表之间做出决定,其中很多不会适用于每个用户,然后为用户可以拥有多个实例的数据创建一个单独的表(例如,以前的工作)与将每个用户的数据分布在多个表之间。
第一种方式更加精简,但我觉得它会使用大量不必要的开销,而第二种方式的结果更容易使用,但会导致大量额外的数据库查询。
一些关联事物的多个实例总是进入另一个表。这个过程称为标准化。
虽然乍一看似乎更复杂,但从长远来看,它会让你的生活更轻松。如果需要(如果您的关键字段被正确索引),像 MySQL 这样的数据库系统可以将表重新组合在一起(非规范化)。
由于多种原因,使用像您描述的那样的非规范化表要困难得多。假设 aPerson
有多个地址。你怎么把它放到主表中? Address1
, Address2
, Address3
? 如果这个人有四个不同的地址怎么办?
使用这样的表将变得更加困难,因为您现在必须在编写的每个查询中处理表中的三列而不是一列。
如果相关的品质取决于用户的类型,并且特定类型的所有用户都具有所有这些品质,那么您可以为每种类型创建一个表格。
CREATE TABLE Type1_Qualities ( id int not null auto_increment 主键, user_id int 引用 (User), qual1 ..., qual2 ..., ... )
Type2 和 Type3 也是如此。这避免了为每个用户提供所有这些无关字段,但比使用通用属性表(如 xception 的答案)进行大量连接更简单。
根据您的数据存储方式,您可能会选择多关系数据结构,这只是一个示例:
CREATE TABLE user (
id int not null auto_increment primary key,
name varchar[60] not null
);
CREATE TABLE attributes (
id smallint not null auto_increment primary key,
name varchar[20] not null,
order smallint --optional
);
CREATE TABLE userattributes (
user int not null references user (id),
attribute smallint not null references attributes(id),
value varchar[100] not null,
order tinyint --optional
);
INSERT INTO textattributes(name) VALUES ('alias'), ('address'), ('hobby')
我将订单字段标记为可选,因为您可能不关心这些
SELECT a.name, ua.value
FROM userattributes AS ua
JOIN attributes AS a
ON ua.attribute = a.id
WHERE user = :user
ORDER BY a.order, ua.order
如果您愿意,您也可以加入用户,但该数据将为每一行重复,或者您可以使用单独的查询从用户获取数据。我个人会为此使用第二个查询。