复合主键和对自然/代理键使用的影响

And*_*ini 8 database sql-server database-design sql-server-2005

我有一个相当简单的问题,关于自然/代理关键用法在明确定义的背景中经常表现出来,并且我将说明.

假设您正在使用SQL Server 2005作为DBMS设计产品的数据库模式.为简单起见,假设只涉及两个实体,它们已映射到2个表,Master和Slave.假使,假设:

  1. 对于单个Master的行,我们可以有0..n Slave条目;
  2. Master中列集(A,B,C,D)是主键的唯一候选者;
  3. Master中的B列随时间变化 ;
  4. A,B,C,D是varchar,decimal和bigint列的混合.

问题是:您将如何为这些表设计键/约束/引用?你愿意(争论你的选择):

  1. 在Master上的(A,B,C,D)和Slave上的相关复合外键上实现复合自然键,或
  2. 在Master上引入代理键 K,比如在Slave上带有相关(单列)外键的IDENTITY(1,1)列,在Master(A,B,C,D)上添加UNIQUE约束,或者
  3. 使用不同的方法.

至于我,我会选择2),主要是因为假设3)和表现方面,但我想听听别人的意见(因为关于这个话题有相当公开的辩论).

谢谢

gbn*_*gbn 8

我会选择2.保持简单.

它为有用的聚簇索引(这是SQL Server中PK的默认值)勾选框(窄,数字,不变,严格单调增加).

A,B,C,D但是,如上所述,您需要强制使用唯一性来保持数据完整性.

选项1在概念上没有任何错误,但只要您在"master"上需要更多索引,那么宽聚簇密钥就会成为一种负担.或者更多的工作来确定哪个索引最适合作为群集.

编辑:

如有任何混淆

选择哪个索引是集群的选择与密钥的选择是分开的


Ton*_*ews 6

您的假设(3)倾向于建议选项(2),因为当B改变时处理Master的主键的级联更新是不方便的并且可能是耗时的.

当然,这取决于这种情况发生的频率:如果它是你期望"一直"发生的事情,那么它表明(A,B,C,D)是一个糟糕的主键选择; 另一方面,如果它很少发生,那么(A,B,C,D)可能是主键的一个很好的选择,并且在Slave中拥有这些列可能有一些优点(不需要加入Master所有的找出那些列值的时间).


nvo*_*gel 5

1,2或3.没有足够的信息来确定代理是否必要或有多么有用.任何复合键属性是否也是Slave表中某些键或约束的一部分?还有其他一些Master可以用作外键吗?密钥值可能改变的事实不应该是决定因素,因为任何密钥值都可能需要改变 - 代理也不例外.

关于这个话题有一个公开辩论

不幸的是,大部分辩论是基于错误的假设,即您需要在代理或自然键之间进行选择.正如您的选择2正确地建议您可以在需要时使用两者.一个不能替代另一个,因为不同属性上的简单键和复合键显然意味着数据模型中的不同内容,并对数据实施不同的约束.