在SQL Server 2008中,如何设计1:1和1:m关系?
答案 0 :(得分:22)
任何关系都要求“父”表(一方)具有唯一标识每一行的主(或唯一)密钥(PK),而“子”表(另一方)具有外键列或列,必须使用与父表中主键的某些现有值[s]相同的值填充。如果你想要一对多(1-M)的关系,那么外键应该是子表中可以重复的普通属性(列或列)(可以有许多行具有相同的值)
如果你想要一对一(1-1)关系,那么外键本身应该是子表中的主键或唯一索引,以保证子表中最多只有一行具有该值
1-1关系有效地将表中的属性(列)分成两个表。这称为垂直分割。这通常是为子类化表实体完成的,或者,由于另一个原因,如果表中列的使用模式表明需要访问的几个列比其余的列。 (假设一个或两个列每秒访问1000次,其他40个列每月只访问一次)。以这种方式对表进行分区实际上将优化这两个不同查询的存储模式。
<强>子类即可。以上实际上创建了1到0或1的关系,用于所谓的子类或子类型关系。当您有两个共享大量属性的不同实体时会发生这种情况,但其中一个实体具有另一个不需要的其他属性。一个很好的例子可能是员工和 SalariedEmployees 。 Employee 表将具有所有员工共享的所有属性, SalariedEmployee 表将与Employees存在(1-0 / 1)关系,并具有其他属性(薪资, AnnualVacation 等)只有受薪员工才需要。
如果您真的想要1-1关系,那么您必须添加另一种机制来保证子表将始终为父表中的每个记录/行创建一条记录。通常,执行此操作的唯一方法是在用于插入数据的代码中强制执行此操作(在触发器,存储过程或数据库外部的代码中)。这是因为如果在两个表上都添加了引用完整性约束,这些表要求行始终同时存在,那么就不可能在不违反其中一个约束的情况下向任一行添加行,并且不能向两者添加行桌子在同一时间。
答案 1 :(得分:7)
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null [Primary Key, Unique]
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( ForeignKeyCol )
References ParentTable( PrimaryKeyCol )
)
在这种情况下,对于给定的ParentTable主键值,我在ChildTable中永远不会有多行。请注意,即使在一对一关系中,其中一个表是“父”表。纯粹在实现方面,一对一关系与一对多关系的区别在于ChildTable的外键值是否具有唯一键或主键约束。
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( PrimaryKeyCol )
References ParentTable( PrimaryKeyCol )
)
在这种情况下,对于给定的ParentTable主键值,我可以在ChildTable中有多行。
答案 2 :(得分:1)
存在1:1的关系,其中表A和表B仅相互存在一次。 示例:学生有1个硕士生记录。学生将是表A和表B中的记录。表B将包含表A中学生记录的外键(反之亦然)
存在1:m的关系,其中表A可由表B中的许多条目引用或链接。 示例:学生可以从图书馆中取出几本书。学生再次成为表A,书可以是表B中的条目。表B中的条目将包含检查书籍的外键,许多书籍可以引用同一个学生。