何时使用自动递增的主键,何时不使用?

时间:2010-02-02 17:39:41

标签: sql database-design

我正在试图找出决定是否将自动递增整数作为表的主键添加的“最佳实践”。

假设我有一张包含化学元素数据的表格。每个元素的原子序数是唯一的,永远不会改变。因此,不是为每列使用自动递增整数,而是使用原子序数可能更有意义,对吗?

如果我有一张书桌,那也是如此吗?我应该使用ISBN还是主键的自动递增整数?或者包含每个人的SSN的员工表?

7 个答案:

答案 0 :(得分:13)

Stack Overflow上有很多已经解决的问题,可以帮助您解决问题。请参阅herehereherehere

您应该寻找的术语:surrogated keys

希望它有所帮助。

答案 1 :(得分:10)

这是一个备受争议的问题,双方都有很多情绪。

以我的拙见,如果有一个好的,可用的自然键 - 比如ISBN - 我就用它。无论如何,我打算将它存储在数据库中。是的,自然键通常大于整数自动增量键,但我认为这个问题过于夸张。磁盘空间今天很便宜。我更担心它需要更长的时间来处理。如果你在谈论一个80字节的文本字段作为主键,我会说不。但如果您考虑使用10字节的ISBN而不是8字节的大整数,我无法想象这会带来很大的性能损失。

有时自然键具有性能优势。例如,假设我想找到已售出的给定书籍的副本数量。我不关心Book主记录中的任何数据。如果主键是ISBN,我可以简单地写一下“select count(*)from sale where isbn ='143573338X'”。如果我使用自动增量密钥,我将不得不进行连接以查找isbn,并且查询变得更复杂和更慢,例如“使用(bookid)从book join sale中选择count(*),其中isbn ='143573338X' ”。 (我可以向你保证,由于这个特定的ISBN适用于我的书,销售记录的数量非常少,所以加入和阅读一个额外的记录是一个很大的百分比差异!)

自然键的另一个优点是,当您必须处理数据库并查看按键引用此表的记录时,很容易看到它们所指的记录。

另一方面,如果没有好的,明显的自然键,不要试图拼凑一个疯狂的。我看到人们试图通过将客户名字的前6个字母,他的出生年份和他的邮政编码连接在一起来制作一个自然的密钥,然后祈祷这将是独一无二的。那种愚蠢只会给自己制造麻烦。通常人们最终会接受一个序列号,以确保它是独一无二的,在那一点上,为什么要这么麻烦?为什么不直接使用序列号作为键?

答案 2 :(得分:4)

你已经有了这个想法。

如果您正在建模的项目中不存在唯一键,则应将自动增量用作唯一键。因此,对于Elements,您可以使用原子序号或书籍ISBN号。

但是如果人们在留言板上发布消息,那么这些消息需要一个唯一的ID,但不要自然包含,所以我们从列表中分配下一个号码。

在可能的情况下使用自然键是有意义的,只需记住将字段作为主键并确保为性能编制索引

答案 3 :(得分:3)

我在自动递增整数方法时遇到的主要问题是当您导出数据以引入另一个数据库实例,甚至存档和还原操作时。由于整数与它引用的数据无关,因此在将数据还原或添加到现有数据库时无法确定是否存在重复项。如果你想在行中包含的数据与PK之间没有关系,我只想使用一个guid。用户不太友好,但它解决了上述问题。

答案 4 :(得分:3)

关于使用ISBN和SSN,您必须考虑其他表中有多少行将通过外键引用这些行,因为这些ID将占用比整数更多的空间,因此可能导致浪费磁盘空间可能会加剧性能。

答案 5 :(得分:2)

我正在试图找出决定是否将自动递增整数作为表的主键添加的“最佳实践”。

将其用作数据集的唯一标识符,其中PKey不属于用户管理数据。

假设我有一张包含化学元素数据的表格。每个元素的原子序数是唯一的,永远不会改变。因此,不是为每列使用自动递增整数,而是使用原子序数可能更有意义,对吗?

如果我有一张书桌,那也是如此吗?我应该使用ISBN还是主键的自动递增整数?或者包含每个人的SSN的员工表?

ISBNs / SS#由第三方分配,由于存储空间大,因此唯一标识行的方式效率极低。请记住,当您连接表时,PKeys非常有用。当像Integer这样的小而紧凑的格式可用时,为什么要使用像ISBN这样的大数据格式作为唯一标识符?

答案 6 :(得分:0)

老话题我知道,但另外要考虑的是,鉴于大多数RDBMS使用PK在磁盘上布局块,使用自动递增PK只会大大增加您的争用。这对你的宝贝数据库来说可能不是一个问题,但是相信我这可能会导致城镇大规模的性能问题。

如果必须使用自动递增ID,可以考虑将其用作PK的部分。最后把它搞得保持独特......

此外,最好在跳到代理人之前用尽自然PK的所有可能性。人们通常对此很懒惰。