我有一个表[Users]和另一个表[Administrators]链接1:0..1。合并这些表是最佳做法吗?我已经阅读了很多关于SO的答案,说明拆分表只是一对多关系所必需的。
我将它们分开的原因是我可以使用AdministratorId而不是一般的UserId来引用管理员。在其他表中,我的字段应该只包含一个管理员,因此它可以作为参考检查。
答案 0 :(得分:5)
有一条经验法则规定表可以模拟实体/类或实体/类之间的关系,但不能同时模拟两者。但是,这只是一个经验法则,永远不要说永远!
SQL通常存在专用1:1关系表的问题,因为通常发现的唯一的表间约束是外键。但是,FK不要求引用表中存在值。这使得关系1:0..1(“一对零或一”),这通常是可接受的。
严格1:1需要解决方法。由于SQL缺少多个赋值,因此解决方法通常涉及诉诸程序代码,例如两个可延迟的“双向”FK;触发;通过CRUD存储过程强制更新;等
相比之下,在同一个表中建立1:1关系很容易:将两列都声明为NOT NULL
!
答案 1 :(得分:3)
我认为最好的选择是为两个不同的实体Users
和Administrators
设置两个表,可能使用相同的Primary Key
。
CREATE TABLE User
( UserId int
, ... other data --- data for all users
, PRIMARY KEY (UserId)
) ;
CREATE TABLE Administrator
( AdministratorId int
, ... other data --- data for administrators only
, PRIMARY KEY (AdministratorId)
, FOREIGN KEY AdministratorId
REFERENCES User(UserId)
) ;
这样,正如您所提到的,其他表可以引用AdministratorId
:
CREATE TABLE OtherTable
( OtherTableId int
, AdministratorId int
, ... other data
, ...
, FOREIGN KEY AdministratorId
REFERENCES Administrator(AdministratorId)
) ;
优点:
NULL
数据较少。 任何需要JOIN
到Administrator
表的查询都必须只查找几行,而User
的行数可能很大表。如果您只有一个表,那么最终会得到如下代码:
WHERE User.admin = True
可能不容易优化。
答案 2 :(得分:2)
有几个原因可能会让您将它们分开。一种是如果一个表中的记录代表另一个表中的记录的子集。这种模式称为子分类,在您的情况下显然就是这种情况 即使您需要存储的关于管理员的字段(数据)与您需要存储的关于所有用户的数据没有区别,这也是明智之举。另一个原因是,如果几列的使用模式与其余列的使用模式非常不同(访问频率更高)。
答案 3 :(得分:0)
通常以一对一的关系表格。首先,如果它们是需要单独查询的单独实体,或者它们是子类(如您的情况),则单独的表是有意义的。此外,如果主表对于最大记录大小而言变得太大,则以一对一的关系建立附加表是有意义的。最后你得到的情况是现在关系是1-1,但未来有可能是1-many,例如现在你只有一个电话号码,但可能需要稍后存储更多。在这种情况下,继续进行并使其成为一个单独的表格将会更少。
建立1-1关系的关键是将其强制执行为1-1。最简单的方法是使FK字段也成为第二个表中的PK字段。
答案 4 :(得分:0)