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

时间:2011-05-24 10:41:36

标签: sql-server database sql-server-2005 database-design

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

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

  1. 我们可以拥有 0..n 单个Master的行的Slave条目;
  2. Master中的列设置(A,B,C,D) 是主键的唯一候选;
  3. Master中的 B 会随时更改;
  4. A,B,C,D是varchar,decimal和bigint列的 mix
  5. 问题是:您如何为这些表设计键/约束/引用? 你愿意(论证你的选择):

    1. 在(A,B,C,D)上的Master上实现复合自然键,以及Slave上的相关复合外键,或
    2. 在Master上引入一个代理键 K,在Slave上写一个带有相关(单列)外键的 IDENTITY(1,1)列,添加一个UNIQUE对Master(A,B,C,D)或
    3. 的约束
    4. 使用其他方法。
    5. 至于我,我会选择2),主要是因为假设3)和表现明智,但我想听听别人的意见(因为关于这个话题存在相当公开的辩论)。 / p>

      谢谢

4 个答案:

答案 0 :(得分:8)

我会选择2.保持简单。

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

如上所述,您需要强制A,B,C,D上的唯一性,以保持数据的完整性。

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

编辑:

如果有任何混淆

  

选择哪个索引进行聚类与密钥

的选择是分开的

答案 1 :(得分:6)

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

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

答案 2 :(得分:5)

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

  对此有一个公开辩论   主题

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

答案 3 :(得分:0)

<强>三

第一个建议可能是删除composte键并为自动键添加一个新字段,这与其他字段无关。掌握和详细表格。

它可以是整数自动增量键或全局唯一标识符。将复合键保存在任何S.Q.L.服务器品牌,很难,有时也很难。

但是,如果您需要将复合键保留在主表中,您可能仍然想知道如何处理从表主键。许多开发人员通常使用相同的字段作为主键,从主表,将其放在slave / detail表上,并添加一个额外的连续整数键。但是,正如您所提到的,如果您必须更改主表的键,并保留已存在的详细信息行,则会遇到参考完整性约束的问题。

总结:我建议,为slave表添加一个新字段,该字段与master表无关,将字段的外键添加到slave / detail表,引用master表。保持详细主键和外键到主表,独立。