关于数据库:每个表都应该有一个主键吗?

Should each and every table have a primary key?

我正在创建数据库表,但没有为其分配逻辑主键。所以,我想把它放在没有主键的地方,但我对此感到有点内疚。我应该吗?

每个表都应该有主键吗?


简短回答:是的。

长回答:

  • 你需要你的桌子能和什么东西连在一起
  • 如果您希望表是集群的,则需要某种主键。
  • 如果您的表设计不需要主键,请重新考虑您的设计:最可能的情况是,您缺少了一些东西。为什么要保持相同的记录?

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

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

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

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

而且,由于任何主键都涉及到创建一个唯一索引,所以您应该声明它并获得逻辑一致性和性能。

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

  • 使索引唯一

还有一些非常特别的情况,你不需要主键。

它们主要包括由于性能原因没有任何索引的日志表。


总是最好有一个主键。通过这种方式,它满足第一个正常形式,并允许您沿着数据库规范化路径继续。

正如其他人所说,没有主键有一些原因,但是如果有主键,大多数不会受到伤害。


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

If it doesn't have a primary key, it's not a table!

< /块引用>

马克


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


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

你说你没有自然的钥匙,因此你也没有任何领域的组合来使其独一无二,这使得艺术的钥匙至关重要。

我发现任何时候我没有自然密钥,人工密钥是维护数据完整性的绝对必要条件。如果您确实有一个自然键,那么您可以将它用作键字段。但就个人而言,除非自然键是一个字段,否则我还是更喜欢自然键上的人工键和唯一索引。如果你不把它放进去,以后你会后悔的。


只需添加它,稍后如果没有添加(选择、删除),您会很抱歉。链接等)


在每一张桌子上放一个pk是一个很好的实践,但这不是必须的。最可能的情况是,根据需要,您需要一个唯一的索引和/或一个聚集索引(不管是不是pk)。

查看联机丛书(用于SQL Server)上的"主键"和"聚集索引"部分。

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

但是,也可以访问:http://www.aisintl.com/case/primary_and_foreign_key.html


我知道为了在.NET中使用GridView的某些功能,需要一个主键,以便GridView知道哪些行需要更新/删除。一般的做法应该是拥有一个主键或主键集群。我个人更喜欢前者。


为了让它成为未来的证据,你真的应该这样做。如果你想复制它,你需要一个。如果你想加入另一张桌子,你的生活(以及那些明年必须维持生活的可怜的傻瓜)会轻松得多。


我总是有一个主键,即使在开始的时候我还没有一个目标。有好几次,我最终需要一个pk在一个没有pk的表中,以后再放入它总是比较麻烦。我认为总是包括一个更好。


我负责维护由离岸开发团队创建的应用程序。现在,我在应用程序中遇到了各种各样的问题,因为原始数据库模式没有在某些表上包含主键。所以请不要让别人因为你的糟糕设计而受苦。最好在表上有主键。


如果使用Hibernate,则无法创建没有主键的实体。如果使用的是用纯SQL/DDL脚本创建的现有数据库,并且没有添加主键,则此问题可能会产生问题。


总之,不需要。但是,您需要记住,某些客户端访问CRUD操作需要它。为了将来的校对,我总是使用主键。


不同意建议的答案。简短的回答是:不。

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

但是,也有一些情况,例如记录时间序列数据,其中不需要存在这样的键,只需要占用内存。使一行独一无二只是…不需要!

一个小例子:表A:日志数据

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

不需要主键。

表B:用户

1
Columns: Id, FirstName, LastName etc.

要用作logdata表的"外键",需要主键(ID)。