可能的重复:
代理与。自然/业务密钥
如果给定两个表,Level1 [ID, Title, Number] Level2 [ID, FKID???, Title, Number]
系统用户了解 Level2 与 Level1 相关,基于 Level1 的编号,我的问题是,您是根据内部 ID 建立关系并“模拟”与“编号”的关系还是简单地使用“数字”字段又可以用了吗?
可能的重复:
代理与。自然/业务密钥
如果给定两个表,Level1 [ID, Title, Number] Level2 [ID, FKID???, Title, Number]
系统用户了解 Level2 与 Level1 相关,基于 Level1 的编号,我的问题是,您是根据内部 ID 建立关系并“模拟”与“编号”的关系还是简单地使用“数字”字段又可以用了吗?
与数据库 ID 而不是自然 ID 相关的两个标准原因是:
这个讨论在这里被打死了。很少有人只保护自然键,大多数人鼓励使用代理键。有人说你可以同时拥有这两者,当然这是真的(使用自然键以便强制执行业务规则。)
如果自然键真的是键(大多数时候不是),我倾向于三思而后行。如果是,那我就用它。
但同样,现实中的大多数自然键都不是键,并且由于各种原因会有重复。例如,在发行国民身份证的国家,发现两个人的身份证号码相同的情况并不少见。
也就是说,如果我走代理键路线,我会像这样设置表格
Level1 [ID, Title, Number] Level2 [ID, FKID references Level1]
无需两次存储标题和编号。
我想这已经被报道过很多次了。
使用 IDENTITY/AUTONUMBER 作为外键几乎总是更安全。
大多数自然键都可以复制(即使是错误的)。
在我的国家,我们甚至有个人身份证号码的问题 X-)。
如果“数字”列可用于以自然方式关联两个表,我不会强制基于内部(代理)键的关系。
一方面,“数字”列可能已经足够好,因此您不会在 ID 列上浪费空间。另一方面,如果“编号”列没有正确的特征(可能会更改、可能难以索引等),那么代理 ID 可能是更好的选择。
这一切都归结为“数字”列的语义。
如果(例如 SSN 或员工 ID)您确信密钥的稳定性,有时最好使用自然密钥。
使用代理键,FK 本质上是从一个系统生成的#到另一个系统生成的#的关系。在极端情况下,这种人为的关系可能与现实完全不同步。
其他海报评论了当自然键必须改变时发生的混乱。当然那是个问题。但是值得研究一下这些异常发生的频率 - 尾巴(异常)是否应该摇狗(你的设计) - 在每种情况下?
我对此并不狂热,但我同意在同一个数据库中使用自然键和代理键混合使用不同的约定是不方便的。
如果 Natural 键是多个字段,例如 DateOfBirth + LastName + Department(或一些这样奇怪的东西),那么您最好使用人工键。
上述所有论点都处于数据模型的逻辑级别。在物理层面上,您的情况、服务器和性能限制将决定您的决定。最好不要过早优化。