每个表都应该有一个主键吗?
#1 楼
简短答案:是。长答案:
您需要将表可连接到某些对象上
如果要对表进行集群,您需要某种主键。
如果表设计不需要主键,请重新考虑您的设计:很可能您丢失了某些东西。为什么要保留相同的记录?
在MySQL中,如果您没有明确指定InnoDB存储引擎,它总是会创建一个主键,从而增加了一个您无权访问的列。 >
请注意,主键可以是复合键。
如果您有多对多链接表,则可以在链接中涉及的所有字段上创建主键。因此,您可以确保没有两个或多个描述一个链接的记录。
除了逻辑一致性问题之外,大多数RDBMS引擎都将受益于将这些字段包含在唯一索引中。
并且由于任何主键都涉及创建唯一索引,因此您应该对其进行声明并获得逻辑一致性和性能。
请参阅我的博客中的本文,以了解为什么应始终在以下位置创建唯一索引:唯一数据:
使索引唯一
PS在某些非常特殊的情况下,您不需要主键。
大多数情况下,它们都包含出于性能原因而没有任何索引的日志表。
评论
他们仍然有一个主键,复合键
– kristof
2009年5月8日14:57
@annakata:他们应该有一个复合主键
– Quassnoi
2009年5月8日14:57
“并且,因为任何PRIMARY KEY都涉及创建UNIQUE索引”对于Oracle而言并非如此。可以使用非唯一索引来强制执行主键。实际上,有时需要唯一约束和PK约束使用非唯一索引。
–Stephanie Page
13年5月31日19:47
只是对“为什么要保持相同的记录?”这个反问。请注意,仅添加PK并不能确保没有重复。 PK通常对用户不可见,因此重要的是在可见字段中,该字段可能包含重复数据。根据您的设计,这是否可取。
–罗斯科
15年3月18日在21:05
键与可连接性无关。集群参数取决于您所使用的DBMS,并且混合了逻辑和物理考虑因素。
–琼·赫格兰德
19年4月29日在11:04
#2 楼
始终最好拥有一个主键。这样,它就可以满足第一个标准形式,并允许您沿着数据库规范化路径继续。正如其他人所述,有一些原因没有主键,但是如果有主键,大多数原因不会受到损害。是主键
评论
@PaulSuart数据不必始终保持其正常形式。实际上,当数据变得庞大时,不应将其保存为正常形式,否则对于进行表联接等的查询而言,访问数据的速度将非常慢。正常形式是一种“理想化”,实际上只有在预计数据不会增长的情况下才有可能巨大。
–起搏器
2012年6月13日的1:39
#3 楼
在几乎没有主键的情况下创建表的任何时候,以为我不需要一个主键,所以我最后回头添加了一个。现在,我甚至使用自动生成的身份字段(用作主键)来创建联接表。评论
连接表是一个主键-一个组合键,由要连接的两个记录的PK组成。例如。创建表PersonOrder(PersonId int,OrderId int,PRIMARY KEY(PersonId,OrderId))。
–基思·威廉姆斯(Keith Williams)
09年5月14日在12:35
是的,但是如果链接表还具有第三个属性,该说“ OrderDate”。您是否还将其添加到组合键中?恕我直言,否-因为它可以进一步还原,并且不能满足主键应具有的不可还原特征。
– Steve K
2012年3月29日上午10:14
#4 楼
除了极少数情况(可能是多对多关系表,或者是您临时用于批量加载大量数据的表)之外,我会说一句:如果没有主键,则它不是表!
Marc
评论
严格说来这句话是错的。表可以是您的查询语言创建的“查看表”。 RDBMS由关系而不是表组成。那句话应该说:“如果没有主键,那就不是关系!”。
– Steve K
2012年3月29日上午10:17
或者,“如果没有候选键,那么它不是关系表”。但是,在极少数情况下,可以使用不代表关系的表。
– Walter Mitty
18年2月13日在0:34
为什么多对多表没有主键?您可以创建一个单独的主键,然后为外键替代创建唯一的索引。我认为最好在每个表上都有一个主键。即使在批量加载表上,您可能也要单独标识一个不包含正在导入的数据的主键,因为它可能有助于您在ETL流程中标识重复记录。在我看来,即使每个表都有更多的存储空间,每个表仍应具有主键。视图创建的表是表的子集,而不是表本身。
–约翰·欧内斯特(John Ernest)
18年7月27日在19:09
在多对多关系表中,您可以创建一个由两个关系的ID组成的复合主键。
– Jaap
18-10-17在10:45
#5 楼
只需添加它,以后您却没有(选择,删除,链接等)时会后悔#6 楼
您是否需要将此表加入其他表?您需要一种唯一标识记录的方法吗?如果答案是肯定的,则需要一个主键。假设您的数据就像一个客户表,其中包含客户人的名字。可能没有自然键,因为您需要地址,电子邮件,电话号码等来确定此Sally Smith是否与Sally Smith不同,并且您将把该信息存储在相关表格中,因为此人可以使用多种电话,地址。 ,电子邮件等。假设Sally Smith与John Jones结婚并成为Sally Jones。如果您桌上没有万能钥匙,则在更新姓名时,您只是将7位Sally Smiths更改为Sally Jones,即使其中只有一位结婚并更改了她的名字。当然,在这种情况下,如果没有人为钥匙,您怎么知道哪个萨利·史密斯住在芝加哥,哪个人住在洛杉矶?您说您没有自然钥匙,因此您没有任何自然钥匙领域的组合使任何一个都变得独特,这使得人工密钥变得至关重要。
我发现,无论何时我没有自然密钥,人工密钥都是维护数据完整性的绝对必要。如果您有自然键,则可以将其用作键字段。但是就个人而言,除非自然键是一个领域,否则我仍然更喜欢人工键和自然键上的唯一索引。如果您不投入,以后会后悔的。
#7 楼
不同意建议的答案。简短的答案是:NO。主键的目的是唯一地标识表上的一行,以便与另一个表建立关系。传统上,自动递增的整数值用于此目的,但是对此有一些变化。
在某些情况下,例如记录时间序列数据,存在这样的键是根本不需要,只占用内存。简单地使行变得唯一...不是必需的!
一个小例子:
表A:LogData
Columns: DateAndTime, UserId, AttribA, AttribB, AttribC etc...
不需要主键。
表B:用户
Columns: Id, FirstName, LastName etc.
主键(Id)用作LogData表的“外键”。
#8 楼
在每张桌子上都有一个PK是一个好习惯,但这不是必须的。根据您的需要,很可能您将需要唯一索引和/或聚集索引(是否为PK)。在联机丛书中查看“主键和聚集索引”部分(适用于SQL)服务器)
“ PRIMARY KEY约束标识具有唯一标识表中一行的值的列或列集。表中的两行不能具有相同的主键值。您不能输入主键中任何列的NULL。我们建议使用一个小的整数列作为主键。每个表都应有一个主键。符合主键值的一列或多列组合称为候选键。“
,然后再检查一下:http://www.aisintl.com/case/primary_and_foreign_key.html
评论
还要检查此内容,sql-server-performance.com / 2006 / primary-key-index-clustered
– endo64
2012年2月9日在11:47
该页面非常愚蠢。首先,出于性能原因需要主键。通过阅读他的页面,我了解到将ID添加到书本表是没有用的,因为书本的文本是唯一的。显然,这家伙从未与数据库打过交道,但他在理解自己批评的内容时也遇到了问题。页面写的是1)PK值引用行2)您可以按任何列集连接2个表。没有矛盾。令人惊讶的是,一篇学术文章的作者不了解关系理论的基础知识。
– Federico Razzoli
2015年10月11日10:23
“首先,出于性能原因需要主键”,这是不正确的,PK不会直接影响性能。没有PK可能会导致许多问题(标识行,联接等),但性能不是其中之一。当您在表上创建PK时,SQL Server创建一个唯一集群索引,该索引会影响性能而不是PK本身。举一个真实的例子,我的表在date列上有一个聚集索引,而在GUID字段上有一个PK,这是因为所有行都有日期范围(在我的情况下),因此我的行应在表的date列上按物理顺序排序。
– endo64
16-10-27在8:19
该聚集索引是主键的一种形式,由SQL Server和其他几个DBMS创建。您确定使用它是个好主意吗?例如,在MySQL中,并非出于一些未记录的原因。
– Federico Razzoli
17年7月7日在13:09
请记住,在InnoDB中,GUID不是PK的最佳类型。所有索引都包含对PK的引用,因此PK越大,所有其他索引都越大。
– Federico Razzoli
17年3月28日在21:37
#9 楼
我知道,为了在.NET中使用gridview的某些功能,您需要一个主键才能使gridview知道需要更新/删除的行。通常的做法是拥有一个主键或主键集群。我个人更喜欢前者。#10 楼
要使其成为未来的证明,您确实应该这样做。如果要复制它,则需要一个。如果您想将它添加到另一个桌子上,您的生活(以及明年必须维护的可怜的傻瓜的生活)将变得更加轻松。评论
我还没有确信这是必要的,但是“这样做,是因为否则将需要以后再处理后果”,足以使我犯错。如果似乎有必要尝试将其缩小,我总是可以稍后再删除该列...
–ArtOfWarfare
19年6月10日在3:13
#11 楼
我负责维护离岸开发团队创建的应用程序。现在我在应用程序中遇到各种问题,因为原始数据库架构在某些表上不包含PRIMARY KEYS。因此,请不要让别人因为您的设计不佳而受苦。在表上拥有主键始终是一个好主意。#12 楼
我总是有一个主键,即使一开始我还没有一个目的。有几次,当我最终需要一个没有一个的表中的PK时,以后再放入它总是比较麻烦。我认为始终包含其中还有更多好处。#13 楼
简而言之,没有。但是,您需要记住,某些客户端访问CRUD操作需要它。为了将来验证,我倾向于始终使用主键。#14 楼
如果您使用的是Hibernate,则无法创建没有主键的实体。如果使用的是使用普通sql / ddl脚本创建的现有数据库,并且未添加任何主键,则此问题可能会引起问题。#15 楼
晚了聚会,但我想加两分钱:每个桌子都应该有主键吗?
如果你是谈到“关系性阿尔贝格拉”,答案是肯定的。通过这种方式对数据建模需要实体和表具有主键。关系代数的问题(除了事实之外,它还有20种不同的,错配的味道)是它仅存在于纸张中。您不能使用关系代数构建现实世界的应用程序。
现在,如果您谈论的是来自现实世界应用程序的数据库,则它们可以部分/大部分遵循关系代数,最好的,其余的都丢弃。此外,如今数据库引擎提供了巨大的非关系功能(现在是2020年)。因此,在这种情况下,答案是否定的。在任何情况下,我的真实表中有99.9%具有主键,但是有合理的例外。案例:事件/日志表(多个索引,但看不到单个键)。最重要的是,在遵循实体/关系模型的事务性应用程序中,这样做很重要在几乎所有表中都具有主键是合理的。如果您决定跳过表的主键,请确保您有充分的理由这么做,并且准备为自己的决定辩护。
评论
您能否提供有关该表的更多详细信息?答案可能是“是”。是的,每个表都应具有主键。