主键和身份之间有什么区别?


73

在SQL Server数据库中,主键和标识列之间有什么区别?列可以是主键,而不必相同。但是,如果没有主键,则列不能是标识。

除了差异之外,PK和“身份”列还提供什么,而仅PK列不提供?


请不要包括问题的答案(而是作为单独的答案发布)。
user4157124 '20

Answers:


90

列绝对可以是身份而不是PK。

身份只是一个自动增加的列。

主键是定义行的一个或多个唯一列。

这两个经常一起使用,但是并不需要如此。


1
实际上,我相信SQL Server确实要求他们这样做,但是其他数据库可能不需要。
Erik Funkenbusch

8
我有99%的肯定不会,但是没有访问实例的权限。

1
然后粘贴在错误的创建表中。这与非身份列为PK一起使用...创建表pktest(nonpk int identity(1,1),pk int主键不为null)
KenJ 2010年

3
+1好答案。PK不必是一个自动递增的数字,但是它对于每个条目必须是唯一的值。要使用不是身份的PK,可能有必要先检查输入的新身份与表中已存在的身份。
Evan Plaice

1
SQL Server将拒绝重复输入以获取主键,这比我们为重复项编写的任何检查都要快。我们处理代码中的拒绝,因此实际上我们已经检查了重复的条目。
RC_Cleland

13

因为乔已经正确回答了上面的问题,所以这个答案更多的是为什么身份和primay键。

身份是SQL控制的值。身份是行功能。至少在SQL Server中,它是按顺序递增或递减值。永远不要修改它,并且值中的空白应该被忽略。身份值在将表B链接到表A时非常有用,因为该值永远不会重复。在每种情况下,身份并不是聚集索引的最佳选择。如果表包含审计数据,则最好在发生日期创建聚簇索引,因为它将以较少的工作量回答“今天和四天之间发生了什么”问题,因为日期的记录在表中是连续的。数据页。

主键使行中的一列或多列唯一。Primay键是一种列函数。在任何表上只能定义一个主键,但是可以创建多个唯一索引来模拟主键。群集主键并不总是正确的选择。考虑一下电话簿。如果电话簿是由主键(电话号码)组成的,则返回“ First Street”上电话号码的查询将非常昂贵。

我遵循的身份和主键通用规则是:

  1. 一律使用身分栏
  2. 在范围查找中使用的一个或多个列上创建聚集索引
  3. 由于将聚簇索引添加到所有其他索引的末尾,因此使聚簇索引保持较窄
  4. 创建主要键和唯一索引以拒绝重复值
  5. 窄键更好
  6. 为联接中使用的每个列创建索引

这些是我的一般规则。


1
您提到身份值永远不会重复。如果手动插入或重新植入,则可以复制它们(subhrosaha.wordpress.com/2012/11/14/…)。如果要保证唯一性约束,例如必须将唯一索引添加到列中。
宽带

8

主键(也称为候选键)是具有唯一性和最小性属性的任何属性集。这意味着一个或多个键列被限制为唯一。换句话说,DBMS不允许任何两行具有这些属性的相同值集。

IDENTITY属性有效地为列创建一个自动递增的默认值。该列不必是唯一的,因此IDENTITY列不一定是键。

但是,IDENTITY列通常打算用作键,因此通常对它具有唯一性约束,以确保不允许重复。


5
如此看来,在这种情况下,单词“身份”是有点用词不当,因为它并不总是唯一的,正如你所指出,因为有其他。您的答案通过强调它只是为列创建一个自动递增的默认值,从而看起来像MySql的AUTO_INCREMENT属性,从而帮助那些对MySql更有经验的人更好地理解Sql Server的Identity属性。谢谢。
詹森·弗兰克

1

根据反馈进行的编辑

键是一行唯一的。这是识别行的一种方式。行可能没有,只有一个或几个键。这些键可能包含一列或多列。

键是具有唯一约束的索引。这将它们与非关键索引区分开来。

任何具有多列的索引都称为“复合索引”。

传统上,主键被视为唯一标识行的主键。可能只有其中之一。

根据表的设计,可能没有主键。

主键就是这样-一个“主键”。它是指定行的唯一标识的主要对象。根据表的设计,这可能是用词不当,并且多个键表示唯一性。

在SQL Server中,主键可能是群集的。这意味着剩余的列将在索引的叶级别附加到此键。换句话说,一旦SQL Server找到了密钥,它也会找到该行(要明确,这是由于群集方面)。

标识列只是一种为行生成唯一ID的方法。

这两个经常一起使用,但这不是必需的。


1
SQL Server不需要主键是聚簇索引。
RC_Cleland 2010年

1
@IanC:“之所以称为主键,是因为这是唯一标识行的键”。这并不是真正的解释,因为ANY键或任何超键唯一地标识一行,而不仅仅是“主”键。“主”键实际上仅表示“首选”或“特殊”键-尽管它只是您想要的特殊。
nvogel 2010年

1
@IanC:危险是,通过以这种方式进行描述,一个不知情的人可能会感觉到表中可能只有一个这样的键,这显然是不正确的。
nvogel

1
@IanC:因为事物具有多个标识符是很常见的,并且数据库的不同用户有时需要使用不同的密钥(例如,开发人员通常使用与最终用户不同的密钥)。原则上,所有候选键都可以起到相同的作用。因此,说我们可以或必须只有一个主键或者主键在任何基本方式上都是特殊的并不是特别有意义。
nvogel

1
我说一个表可以有多个候选键。密钥表示候选密钥,“主”密钥(如果有任何特殊含义)仅表示“候选密钥之一”。与我所知道的所有DBMS一样,SQL Server允许每个表使用多个键。SQL为实现键提供了两个唯一性约束:PRIMARY KEY和UNIQUE(当然在非空列上)。这两种键约束都达到了完全相同的目的。
nvogel

1

您不仅可以将IDENTITY与整数一起使用,还可以将小数位数为0的任何数字数据类型一起使用

主键可以有刻度,但不是必需的。

IDENTITY与PRIMARY KEY或UNIQUE约束结合使用,可让您提供简单的唯一行标识符


0

主键强调唯一性,避免同一列上所有记录的重复值,而标识在列中提供不断增加的数字而无需插入数据。两种功能都可以在同一列上,也可以在不同列上。


0

主要和身份列之间的主要区别

主栏:

  • 主键不能有重复的值。
  • 它为表创建聚簇索引。
  • 可以为任何列类型设置它。
  • 我们需要在插入表时提供主列值。

身份栏:

  • 标识列可以具有重复值。
  • 只能为与整数相关的列(如int,bigint,smallint,tinyint或小数)设置
  • 无需在标识列中插入值。它会根据种子自动插入。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.