所有数据库表都应该有主键吗?

时间:2011-01-07 00:29:56

标签: database primary-key

为每个数据库表提供主键是一种好习惯吗?在我看来,如果没有明确需要主键,那么它只会在我的数据库中更加混乱。

7 个答案:

答案 0 :(得分:13)

当你可能会:

在OLTP数据库中,您几乎总是(在我的情况下总是)拥有某种主键。有时Guid,有时是自动编号/身份字段,有时由应用程序或客户设置。有时甚至是多个领域的组合。这是因为您通常希望唯一地标识表中的任何给定行。

此外,主键是查询优化器使用的约束,它可以提高查找和连接的性能。

当你可能不会:

您唯一没有主键的时间是在“报告”表中,可能在非规范化数据仓库中。

答案 1 :(得分:4)

这不是必需的,但请确保您不需要。主键的用途是,您可以根据(通常是最小的)标准集uniquely identify来自另一行。这允许数据库确保您没有重复数据,例如,这也允许您的数据库符合1st normal form。如果不需要,那么您不需要主键,但请首先仔细考虑它。

不要忘记主键不一定必须是包含任意唯一值的附加列 - 它也可以是一组列,它们共同定义唯一性(例如,一个人的名字,姓氏)和地址簿表中的出生日期)。

答案 2 :(得分:4)

是的,最好在每张桌子上都有一把主键。

但是,并非每个表都应该有一个自动编号ID列。我觉得有必要拼写出来,因为出于某种原因,很多人倾向于在所有表格中加入一个额外的ID,即使已经存在一个非常好的候选人。例如,代表Users <-> Groups的多对多表应使用{user_id, group_id}

除了在门上停止重复之外,主键约束还包含优化器在生成执行计划时使用的信息。

这就是为什么我总是,或者至少在极少数例外情况下,在我创建的所有表上都有一个主键。 实际上,我甚至在报表上创建主键,其中大多数列都是主键的一部分。因为在开发过程中,我会得到至少一个唯一的约束违规,因为我做错了。由于存在大量数据且没有约束,我不会发现错误。

答案 3 :(得分:4)

关系数据库设计中密钥的目的是防止重复数据,从而有助于确保数据完整性。如果您允许重复行,则会产生歧义,潜在的更新异常以及可能不正确的结果。因此,通常每个表应该至少有一个密钥(如果需要,可能多于一个)。通常情况下并非“明确需要”数据完整性!

主键只是表的任何一个键。将一个密钥指定为主密钥可能很有用,但并不是特别重要 - 重要的是每个表至少有一个候选密钥。

数据库文献中非常广泛地涵盖了应该避免重复行的原因。参见:

http://www.dbdebunk.com/page/page/627052.htm

http://www.dbdebunk.com/page/page/638922.htm

http://dl.acm.org/citation.cfm?id=77708

http://www.amazon.com/Practical-Issues-Database-Management-Practitioner/dp/0201485559

答案 4 :(得分:2)

一般情况下是 - 我会为表格提供例外,这些表格只是为报告目的而存储的“真实”数据的汇总版本(即为报告/性能原因而创建的汇总表),但通常我总是有一个主键 - 并且在我的应用程序中,它几乎总是一个自动增量整数,相对于行大小几乎没有额外的空间。

答案 5 :(得分:1)

虽然主键非常有用(并且我一直使用它们),但我们要清楚的是,如果您不需要主键,则无需创建主键。在某些情况下,您不需要一个,其中包括:

  • 一个表,它只收集数据(用于持久性目的)以便自己查询,而与其他表无关,其他表需要查找与
  • 相关的精确行。
  • 您不需要在表格中强制执行任何形式的唯一性

在上述两种情况下,您可能只对表格的汇总信息感兴趣,而不是唯一地识别行。我相信还有其他人。但是不使用主键很好 - 这就是为什么在创建表时不需要它们(在大多数系统中)。

答案 6 :(得分:0)

我有一个由CreateDate分区的表,它不是唯一的。在我的情况下,我决定从该表中删除主键,因为主键索引必须是唯一的这一事实意味着我不能使该索引成为LOCAL索引,而是必须是GLOBAL。这意味着从该表中删除(以及其他操作)会使该主键索引无法使用,使其无效。