每个表都应该有一个主键吗?

我正在创建一个数据库表,我没有给它分配一个逻辑主键。每个表都应该有一个主键吗?

319733 次浏览

简单回答:是的

长一点的回答:

  • 你需要你的桌子可以连接到一些东西上
  • 如果您希望您的表被集群,您需要某种类型的主键。
  • 如果您的表设计不需要主键,请重新考虑您的设计:很可能您遗漏了一些东西。为什么要保留相同的记录?

在MySQL中,如果你没有显式地指定主键,InnoDB存储引擎总是会创建一个主键,从而产生一个你无法访问的额外列。

注意,主键可以是复合键。

如果您有一个多对多链接表,您可以在链接中涉及的所有字段上创建主键。因此,您可以确保没有两条或更多的记录描述一个链接。

除了逻辑一致性问题之外,大多数RDBMS引擎都将受益于将这些字段包含在唯一的索引中。

由于任何主键都涉及创建唯一的索引,因此应该声明它并获得逻辑一致性和性能。

请参阅我博客中的这篇文章,了解为什么应该总是在唯一的数据上创建唯一的索引:

有一些非常,非常特殊情况下,你不需要主键。

大多数情况下,由于性能原因,它们包含没有任何索引的日志表。

简而言之,没有。但是,您需要记住,某些客户机访问CRUD操作需要它。为了将来的校对,我总是倾向于使用主键。

几乎每次我创建一个没有主键的表时,我都认为我不需要主键,最终我会返回并添加一个主键。现在,我甚至用一个自动生成的标识字段作为主键来创建连接表。

我总是有一个主键,即使一开始我还没有想到它的目的。有几次,当我最终需要在一个没有PK的表中输入PK时,总是会遇到更多的麻烦。我认为总是有一个人会有更多的好处。

我知道为了在。net中使用gridview的某些特性,你需要一个主键,以便gridview知道哪一行需要更新/删除。一般的做法应该是有一个主键或主键集群。我个人更倾向于前者。

只要添加就可以了,以后你会后悔没有(选择,删除)。连接等)

为了证明未来,你真的应该这么做。如果你想复制它,你需要一个。如果你想把它加入到另一张桌子上,你的生活(以及那些明年不得不维持它的可怜的傻瓜们的生活)将会轻松得多。

如果你正在使用Hibernate,不可能创建一个没有主键的实体。如果您正在使用使用普通sql/ddl脚本创建的现有数据库,并且没有添加主键,则此问题可能会产生问题

您是否需要将这个表连接到其他表?您是否需要一种唯一标识记录的方法?如果答案是肯定的,则需要一个主键。假设您的数据类似于客户表,其中包含客户的名称。可能没有自然键,因为你需要地址、电子邮件、电话号码等来确定这个Sally Smith和那个Sally Smith是否不同,你将把这些信息存储在相关的表中,因为这个人可能有多个电话、地址、电子邮件等。假设莎莉·史密斯嫁给了约翰·琼斯,变成了莎莉·琼斯。如果你在桌子上没有人工钥匙,当你更新名字时,你只是把7个莎莉·史密斯改成了莎莉·琼斯,尽管其中只有一个结婚并改了名字。当然,在这种情况下,没有人工密钥你怎么知道哪个萨莉·史密斯住在芝加哥哪个住在洛杉矶?

你说你没有自然的密钥,因此你也没有任何字段的组合来使其唯一,这使得人工密钥至关重要。

我发现,在没有天然密钥的情况下,人工密钥对于维护数据完整性是绝对必要的。如果您确实有一个自然键,您可以使用它作为键字段。但就我个人而言,除非自然键是一个字段,否则我仍然喜欢人工键和自然键上的唯一索引。如果你不放进去,你以后会后悔的。

除了少数非常罕见的情况(可能是多对多关系表,或者临时用于批量加载大量数据的表),我会使用以下说法:

如果它没有主键,它就不是表!

马克

最好有一个主键。这样它就满足了第一范式,并允许你沿着数据库规范化路径继续。

正如其他人所述,有一些理由不使用主键,但如果有主键,大多数情况下不会受到损害

我的职责是维护海外开发团队创建的应用程序。现在我在应用程序中有各种各样的问题,因为原始的数据库模式不包含一些表上的主键。所以请不要让别人因为你糟糕的设计而受苦。在表上设置主键总是一个好主意。

在每个表上都有一个PK是一个很好的实践,但这不是必须的。大多数情况下,您需要一个唯一的索引,和/或聚集索引(这是PK与否),这取决于您的需要。

查看联机图书的主键和聚集索引部分(适用于SQL Server)

PRIMARY KEY约束标识具有唯一标识表中一行的值的列或列集。表中的任何两行都不能有相同的主键值。不能为主键中的任何列输入NULL。我们建议使用一个小的整数列作为主键。每个表都应该有一个主键。符合主键值条件的列或列的组合称为候选键。

但是再看看这个:http://www.aisintl.com/case/primary_and_foreign_key.html

不同意建议的答案。简单的答案是:没有

主键的作用是唯一地标识表上的一行,以便与另一个表形成关系。传统上,用于此目的的是一个自动递增的整数值,但也有一些变化。

但在某些情况下,例如记录时间序列数据,根本不需要这样的键,只需要占用内存。使一行唯一很简单……不需要!

一个小例子: 表A: LogData

. txt
Columns:  DateAndTime, UserId, AttribA, AttribB, AttribC etc...

不需要主键。

表B:用户

Columns: Id, FirstName, LastName etc.

用来作为LogData表的“外键”的主键(Id)。

虽然来晚了,但我想补充一下我的观点:

每个表都应该有一个主键吗?

  • 如果你谈论的是“关系albegraa”,答案是是的。以这种方式建模数据需要实体和表有一个主键。关系代数的问题(除了它有20种不同的、不匹配的风格之外)在于它只存在于纸上。您不能使用关系代数构建真实世界的应用程序。

  • 现在,如果你谈论的是来自现实世界的应用程序的数据库,他们部分/大部分坚持关系代数,通过采取最好的,忽略它的其他部分。此外,数据库引擎现在提供了大量的非关系功能(现在是2020年)。所以在本例中,答案是没有。在任何情况下,99.9%的实际表都有一个主键,但也有合理的例外。例如:事件/日志表(多个索引,但看不到单个键)。

总之,在遵循实体/关系模型的事务应用程序中,为几乎(如果不是)所有表设置主键非常有意义。如果您决定跳过表的主键,请确保您有一个很好的理由,并准备为您的决定辩护。

我想找到一些像这样的官方的东西——15.6.2.1集群索引和辅助索引- MySQL

如果表没有PRIMARY KEY或合适的UNIQUE索引,InnoDB内部会在一个包含行ID值的合成列上生成一个名为GEN_CLUST_INDEX的隐藏聚集索引。行是根据InnoDB分配给这样一个表中的行的ID来排序的。行ID是一个6字节的字段,随着新行插入而单调增加。因此,按行ID排序的行在物理上按插入顺序排列。

为什么不自己创建主键呢?此外,ORM不能识别这个隐藏的ID,这意味着您不能在代码中使用ID。