我正计划建立一些数据库项目。
其中一个表有很多属性。
我的问题是:什么更好,将班级划分为2个单独的表格或将所有表格分成一个表格。下面是一个例子
create table User { id, name, surname,... show_name, show_photos, ...)
或
create table User { id, name, surname,... )
create table UserPrivacy {usr_id, show_name, show_photos, ...)
我认为性能相似,因为我可以使用索引。
答案 0 :(得分:4)
最好将所有属性放在同一个表中。
如果您开始在表格中存储属性名称,那么您将在数据库中存储元数据,这会破坏第一个正常形式。
此外,将它们全部保存在同一个表中可以简化您的查询。
你愿意:
SELECT show_photos FROM User WHERE user_id = 1
或者
SELECT up.show_photos FROM User u
LEFT JOIN UserPrivacy up USING(user_id)
WHERE u.user_id = 1
联接是可以的,但请保留它们以关联单独的实体和1> N关系。
列数有限制,只有当您认为可能达到此限制时才会执行其他操作。
将名称值对存储在单独的表中是有正当理由的,但是担心添加列不是其中之一。例如,在某些情况下,创建名称值表可能使您更容易查询属性列表。但是,大多数数据库引擎(包括PHP中的PDO)都包含反射方法,您可以轻松获取表的列列表(实体的属性)。
另外,请注意,User上的id字段应该是user_id,而不仅仅是id,除非你使用的是Ruby,它只强制id。 'user_id'是首选,因为只有id,您的联接看起来像这样:
ON u.id = up.user_id
这看起来很奇怪,首选方式是:
ON u.user_id = up.user_id
或更简单:
USING(user_id)
不要害怕'添加另一个属性'。这是正常的,没关系。
答案 1 :(得分:2)
我会说2个单独的表,特别是如果你使用的是ORM。在大多数情况下,最好让每个表对应一个特定的对象,并使其字段或“属性”成为描述该对象所需的东西。
您不需要'show_photos'来描述用户,但您确实需要它来描述UserPrivacy。
答案 2 :(得分:0)
如果所有隐私属性都可以为空,则应考虑拆分表格,并且最有可能的值为NULL
。
这将帮助您保持主表更小。
如果隐私属性大部分都会被填充,那么拆分表是没有意义的,因为它需要额外的JOIN
来获取数据。
答案 3 :(得分:0)
由于这似乎是一对一的关系,我通常会将它全部保存在一个表中,除非:
您将接近可以存储在一行中的字节数的限制 - 然后您应该将其拆分出来。
或者,如果您通常会单独查询主表,并且在大多数情况下都不需要这些字段。
答案 4 :(得分:0)
如果某些列(identifiable or dependent
上的primary key
)或(来自definite/fixed
集合的值正在使用repeatedly
)表格为这些列并保持一对一的关系。
答案 5 :(得分:-2)
我会建议一些不同的东西。似乎将来你会被要求管理“另一个属性”。您可以只在属性表中添加一行,而不是添加列:
TABLE Attribute
(
ID
Name
)
TABLE User
(
ID
...
)
TABLE UserAttributes
(
UserID FK Users.ID
Attribute FK Attributes.ID
Value...
)
每个人的好评。我的反应应该更清楚了。
我们这样做可以处理特殊情况,客户要求我们以某种方式为他们量身定制我们的网站。我们永远不会将NVP“转移”到查询中的列中 - 我们总是在查询“我应该在这里执行此操作吗?”通过查找为客户列出的特定属性。如果它在那里,那就是'真实'。因此,对于大多数客户而言,大多数布尔列不是大量布尔列,而是大多数布局列,而且这些功能的数量增长趋势,这对我们来说非常有用。
答案 6 :(得分:-2)
为什么没有User表和Features表,例如:
create table User ( id int primary key, name varchar(255) ... )
create table Features (
user_id int,
feature varchar(50),
enabled bit,
primary key (user_id, feature)
)
然后,功能表中的数据如下所示:
| user_id | feature | enabled | ------------------------------- | 291 | show_photos | 1 | ------------------------------- | 291 | show_name | 1 | ------------------------------- | 292 | show_photos | 0 | ------------------------------- | 293 | show_name | 0