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


当前回答

简单的回答是:是的。

长一点的回答:

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

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

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

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

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

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

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

使索引唯一

附注:在一些非常非常特殊的情况下,您不需要主键。

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

其他回答

简单的回答是:是的。

长一点的回答:

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

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

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

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

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

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

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

使索引唯一

附注:在一些非常非常特殊的情况下,您不需要主键。

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

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

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

If you are talking about "Relational Albegra", the answer is Yes. Modelling data this way requires the entities and tables to have a primary key. The problem with relational algebra (apart from the fact there are like 20 different, mismatching flavors of it), is that it only exists on paper. You can't build real world applications using relational algebra. Now, if you are talking about databases from real world apps, they partially/mostly adhere to the relational algebra, by taking the best of it and by overlooking other parts of it. Also, database engines offer massive non-relational functionality nowadays (it's 2020 now). So in this case the answer is No. In any case, 99.9% of my real world tables have a primary key, but there are justifiable exceptions. Case in point: event/log tables (multiple indexes, but not a single key in sight).

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

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

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

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