本地主键还是自动生成的主键?

5
通常情况下,使用本地主键(即现有列或列的组合)或将主键设置为自动生成的整数行哪个更好,这需要根据具体情况而定。
编辑:有人指出这与this question非常相似。
这里的共识是使用代理键,这是我的自然倾向,但是我的老板告诉我,在可能的情况下也应使用自然键。对于此特定应用程序,他的建议可能是最好的,因为行中的名称唯一标识它,并且我们需要保持查看旧数据的能力,因此对名称/规则的任何更改都将意味着新的唯一行。
尽管这里的答案都很有帮助,但它们大多基于主观的“这就是你应该做的”,并且没有引用支持来源。我是否缺少一些必要的阅读材料,或者最佳实践数据库设计高度主观和/或应用程序相关?
6个回答

8

主键

  1. 必须唯一标识一行数据。
  2. 不能包含数据,否则当数据发生更改时会导致主键发生变化(这是不好的)。
  3. 应该在比较操作(WHERE子句/连接)中快速。

理想情况下,您可以为行使用人工(替代)键,最好使用数字整数数据类型(INT),因为它占用空间小且速度快。

主键应由最少数量的字段组成,以仍满足条件1.-3.对于绝大多数表格,此最少数量为:1个字段。

对于关系表(或非常特殊的边缘情况),可能会更高。引用具有复合主键的表格很麻烦,因此不建议为必须单独引用的表格使用复合键。

在关系表中(m:n关系),您将主键的复合键设置为相关表的主键,因此您的复合键自动满足上述三个条件。

如果您绝对确定数据是唯一的且永远不会更改,那么您可以将主键制作为数据。 由于难以保证这一点,我建议不这样做。


@nemo:你可以创建一个人工主键:一个数字或者GUID。数据是记录的有效载荷,我不把ID算作数据。 - Tomalak
只是一个纠正的观点 - 代理键从来不是由数据生成的 - 它们是不可变的。 - D'Arcy Rittich
@OrbMan:是的,我已经重新表述了。我指的是将字段组合成键的过程,但再次阅读该段落后,我发现措辞有误导性。 - Tomalak
糟糕,我把“代理”和“组合”搞混了,对此感到抱歉。 - Tomalak
@Nemo:你所定义的“本地键”是“现有列或列组合”。对我来说,这意味着“数据或数据组合”,这不是一个值得推荐的做法。键应该尽可能抽象,以防止您依赖/使用其实际值。 - Tomalak
显示剩余4条评论

4

谢谢,我在提问之前进行了几次搜索,查看了标签等,但都没有找到答案。 - James McMahon
2
是的,SO的搜索不太好用。你必须知道要查找什么,或者像我经常做的那样,在Google中输入以下内容:site:stackoverflow.com 搜索词。 - cletus

2

始终使用整数。

当需要在其他表格中交叉引用这些元素(使用外键)时,您会感激自己这样做。


1

不管是什么,都要让它变得没有意义(替代键)。有意义的主键会带来致命的问题。


你能进一步解释一下吗?你所说的“有意义”是什么意思? - James McMahon
我认为电子邮件可以被视为“有意义”的主键。 - Valentin V
有意义的 - 典型例子:社会安全号码。键不应具有任何内在的业务含义。 - Otávio Décio
有意义的意思是当你看到它时,它会告诉你一些东西,当你看一个标识时,你无法知道它的含义。 - SQLMenace

1

这是纯粹主义者和实用主义者之间的老战争。 纯粹主义者不接受代理主键,坚持只使用自然主键。 如果你问我,在大多数情况下,我会投票支持增量(代理键)。


0

我认为自动生成是可行的,我想不出有什么理由不这样做。除非你正在开发某种哈希表,但即使如此,我也会坚持使用数据库自动创建的唯一主键。它快速、简单且可靠。如果已经有现成的解决方案,就不要重复造轮子。


不知道为什么你被评分下降了,所以我反对了它,即使你的答案是重复的。 - Mark Brady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接