SQL:主键列.人工"Id"列与"自然"列

And*_*rko 8 sql rdbms primary-key

可能重复:
关系数据库设计问题 - 代理键还是自然键?

当我创建关系表时,有一种诱惑就是选择主键列,这些列的值是唯一的.但出于优化和统一的目的,我每次都会创建人工Id列.如果有一列(或列组合)应该是唯一的,我会为其创建唯一索引,而不是将它们标记为(复合)主键列.

是否真的是一个好的做法总是更喜欢人工"Id"列+索引而不是主键的自然列?

Jus*_*ave 8

这是一场宗教辩论.我个人的偏好是使用合成主键而不是自然主键,但双方都有很好的论据.实际上,只要你是一致和合理的,任何一种方法都可以很好地运作.

如果使用自然键,则两个主要缺点是存在复合键和变异主键值.如果您有复合主键,则显然每个子表中必须有多个列.当实体之间存在许多关系时,从数据模型的角度来看,这可能会变得难以处理.但它也会让人们开始查询时感到悲伤 - 创建使用N-1个N连接条件并获得几乎正确结果的查询非常容易.如果你有自然键,你也不可避免地会遇到自然键值发生变化的情况,然后你必须通过许多不同的实体来改变这种变化 - 这比改变表中的唯一值要复杂得多.

另一方面,如果您使用合成密钥,则会通过添加其他列来浪费空间,增加额外开销以维护其他索引,并且您将增加获得功能重复结果的风险.忘记在业务键上创建唯一约束或者看到组合上存在非唯一索引并假设它是唯一索引非常容易.实际上,我几天前被这个特殊的失败所困扰 - 我已经将复合自然键(使用非唯一索引)编入索引,而不是创建一个唯一约束.愚蠢的错误,但相对容易做出的错误.

从查询编写和命名约定的角度来看,我也倾向于选择合成密钥,因为很高兴知道当你加入表时A的主键是A_ID而B的主键是B_ID .这比记住A的主键是A_NAME和A_REVISION_NUMBER的组合以及B的主键是B_CODE更加自我记录.