2010-02-02 86 views
48

我试图找出决定是否将自动递增整数作为主键添加到表的“最佳实践”。何时使用自动递增的主键,何时不使用?

比方说,我有一个表包含有关化学元素的数据。每个元素的原子序数是唯一的,永远不会改变。因此,而不是使用每列自动递增整数,它可能会更有意义,只是使用原子序数,是正确的?

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

+1

+1我很感兴趣,看看有什么人对此说 – 2010-02-02 17:42:40

+1

这个问题,以各种形式,有点常年......见http://stackoverflow.com/questions/532363/native-primary-key-or例如,自动生成一个。 – mjv 2010-02-02 17:44:11

+0

这不是一个真正值得回答的问题,但这里是我的看法:如果你确定你永远不会有两本书有相同的ISBN或两个具有相同SSN的人,我会毫不犹豫地将这些值作为主键。但这只是我猜测的一种习惯。像Django模型这样的一些ORM系统使得它很难做到这一点,并坚持总是有一个数字增量ID。另一方面,如果你使用PostgreSQL,你甚至可以做*双主键*。我喜欢随时使用它们。 – 2010-02-02 17:49:07

回答

13

有很多已解决的Stack Overflow问题可以帮助您解决您的问题。参见herehere,herehere

您应该寻找的术语:surrogated keys

希望它有帮助。

+0

啊。谢谢。我搜索了一下,但无法弄清楚如何恰当地使用关键词。 – jamieb 2010-02-02 17:47:40

+0

太棒了。乐意效劳。 – 2010-02-02 17:48:26

4

你的想法就在那里。

当您正在建模的项目不存在唯一的密钥时,应将自动增量用作唯一密钥。因此,对于元素,您可以使用原子序数或书号的ISBN编号。

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

很有意义尽可能使用自然键,只记得使该字段作为主键,并确保它被编入索引的性能

+1

“当没有唯一的密钥存在时,应将自动增量用作唯一密钥” - 我无法反驳更多。 – onedaywhen 2011-12-14 09:35:57

2

我想弄清楚的决定“最佳实践”是否将自动递增整数作为主键添加到表中。

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

比方说,我有一个包含有关化学元素数据的表。每个元素的原子序数是唯一的,永远不会改变。因此,而不是使用每列自动递增整数,它可能会更有意义,只是使用原子序数,是正确的?

是的。

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

ISBN/SS#由第三方分配,并且由于其大的存储大小将是一种非常低效的方式来唯一标识一行。请记住,PKeys在连接表格时非常有用。为什么使用像ISBN这样的大数据格式,当像Integer这样的小型紧凑格式可用时,将会有许多文本字符作为唯一标识符?

+0

“假设我有一张包含有关化学元素数据的表格......使用原子序数可能更有意义” - 注意有三个候选键:原子量,符号和数字。是否应该在数据库表中有唯一的约束?值得选择一个作为主键吗?如果是的话,根据什么标准?附:这些问题没有“正确的”答案:) – onedaywhen 2011-12-14 09:42:09

+0

CHAR(13)的值是“大”还是“非常低效”是真的吗? “ – onedaywhen 2011-12-14 09:43:40

2

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

3

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

+0

”将占用比整数大得多的空间,因此可能会导致磁盘空间的浪费“ - 2012年的问候(几乎!):我在这里告诉你,磁盘空间现在和现在一样便宜芯片:) – onedaywhen 2011-12-14 09:45:26

+1

@onedaywhen加入表现仍然是2012年要考虑的事情:-P – 2011-12-14 10:04:00

9

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

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

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

自然的另一个优点关键在于,当你必须在数据库上工作,并且查看通过键引回该表的记录时,很容易看到他们所指的是什么记录。

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

0

老主题我知道,但还有一件事要考虑的是,鉴于大多数RDBMS使用PK在磁盘上布置块,使用自动递增PK将会大大增加您的争用。这可能不是你正在使用的宝贝数据库的问题,但相信我可以在城镇的较大一端引发大规模的性能问题。

如果必须使用自动递增的ID,也许可以考虑使用它作为一个PK的部分。坚持它到底保持独特.....

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

相关问题