我的观点似乎与大多数人(这是一个微不足道的多数)一致,你应该使用代理键,除非自然键是完全明显的并保证不会改变.然后你应该对自然键强制执行唯一性.这几乎意味着代理键几乎所有的时间.
这两种方法的示例,从Company表开始:
1:代理键:表具有ID字段,即PK(和标识).公司名称必须按州独特,因此存在唯一约束.
2:自然键:表使用CompanyName和State作为PK – 满足PK和唯一性.
假设公司PK用于其他10个表中.我的假设,没有数字可以支持,这就是代理关键方法在这里要快得多.
我在自然键中看到的唯一令人信服的论点是多个表使用两个外键作为自然键.我认为在这种情况下它是有道理的.但如果你需要重构,你可能会遇到麻烦;我认为这超出了这篇文章的范围.
有没有人看到一篇文章比较使用代理键的一组表与使用自然键的同一组表的性能差异?环顾四周,谷歌并没有产生任何有价值的东西,只是进行了大量的理论研究.
重要更新:我已经开始构建一组回答这个问题的测试表.它看起来像这样:
> PartNatural – 使用的零件表
唯一的PartNumber作为PK
> PartSurrogate – 部分表
使用ID(int,identity)作为PK和
PartNumber上有一个唯一的索引
> Plant – ID(int,identity)为PK
>工程师 – ID(int,identity)为PK
每个部件都连接到一个工厂,工厂的每个部件都与工程师联系在一起.如果有人对这个测试床有问题,现在是时候了.
解决方法
很多hoohah(在这个问题上的“辩论”中)可能是由于什么是错误的假设 – 你必须在其他表中使用主键进行连接和外键.这是错的.您可以使用任何键作为其他表中的外键的目标.它可以是主键,备用键或任何唯一索引或唯一约束.对于连接,你可以使用任何东西来连接条件,它甚至不必是一个键,或一个idex,甚至独特! (虽然如果它不是唯一的,你会在它创建的笛卡尔积中得到多行).