主键和身份有什么区别?

问题描述 投票:0回答:4

当两者都标识出唯一的行时,它的用途是什么?为什么人们使用标识列作为主键?任何人都可以简单描述答案吗?

sql database rdms
4个回答
2
投票

主键是一个逻辑概念 - 它是您唯一标识表中每条记录的方法。有几种类型的主键 - 自然键使用来自业务域的数据属性,该属性保证具有主键(唯一,非空,不变性)的要求,例如社会安全号,复合键是密钥由多列组成(通常用于“父子关系”),系统创建代理键;它可以是自动增量或标识列。

身份是一种数据类型。它用作代理主键非常有用,因为它具有所需的所有属性。除了作为主键之外,你不太可能将身份类型用于其他目的,但没有什么可以阻止你这样做。

因此,并非所有主键都使用标识数据类型,并非所有标识列都是主键。


1
投票

主键是一种唯一键。事实上,它是一个限制(约束),特定列(或者,通常情况下,列集)的值在不同的行中不能相同(即使使用插入/更新手动/显式设置为相同的值) 。

主/唯一键不需要是自动递增的。事实上,它根本不需要是整数 - 它可以是文本或其他类型。

主键比通常的唯一键更严格,因为它通常意味着NOT NULL,除此之外,每个表只允许一个主键(除了主键之外,每个表允许几个唯一键)。

创建主/唯一键通常会隐式创建索引,以便更快地对该列进行搜索和约束检查。

例如。如果my_columnmy_table列被标记为主键或唯一键,则不能这样做:

INSERT INTO my_table (my_column, other_column, third_column)
    VALUES (10, …, …);
INSERT INTO my_table (my_column, other_column, third_column)
    VALUES (10, …, …);  -- the same value for my_column again

您的RDBMS中的标识是其他RDBMS可以调用auto_increment或serial的标识。这只是一个特性,在行插入操作期间,特定列在未显式设置为某个值时会自动初始化为(最常见的)连续整数值。

例如。如果my_columnmy_table列标记为auto_increment / serial / identity,则可以执行以下操作:

INSERT INTO my_table (other_column, third_column) VALUES (…, …);
    -- not specifying any value for my_column manually,
    -- it'll be initialized automatically to some value
    -- (usually an increasing integer sequence)

Auto_increment / serial / identity通常不保证自动值的严格后果(特别是在中止事务的情况下)。

具体而言,documentation for TRANSACT-SQL说身份不保证:

  • 唯一性(使用唯一/主键来强制执行);
  • 严格的后果。

更新:作为a_horse_with_no_name suggested,“identity”似乎不仅是特定RDBMS(例如Microsoft SQL Server)中常见的auto_increment / serial / identity功能的名称,而且还是ANSI SQL标准定义的名称。

AFAIK,它与我上面描述的不同(关于实现中常见的auto_increment / serial / identity功能)。我的意思是它使列值自动用整数序列初始化,但不保证唯一性和严格的后果。

尽管如此,我认为,与MySQL / PostgreSQL中的auto_increment / serial列不同,ANSI-SQL标准的generated always as identity列不允许在INSERT或UPDATE中手动设置其值(仅自动设置)。


0
投票

主键所需的唯一编号和主键值不能为null,可以通过标识获取,我们不需要手动添加在表中添加的每个新记录。

当记录由于某种原因在表中插入失败时,sql server中的标识也会增加。


0
投票

在数据库表中,每一行都应该是唯一的,并且您需要能够唯一地标识特定行。

给定的表可能有一个或多个具有唯一值的列,因此这些列中的任何一个都可以完成这项工作。也可能存在两个或更多列,虽然它们本身不是唯一的,但形成独特的组合。那也行。

可以唯一标识行的任何列或列组合称为候选键。原则上,您可以选择任何您喜欢的键,但您需要确保唯一性持久。例如,在一个小的人员表中,给定的名称可能是唯一的,但您冒着与下一个额外的人吹的风险。

主键是您指定为首选键的候选键。例如,人员表可以具有许多独特属性,例如电子邮件地址,移动电话号码等。主键是您优先选择的属性。

以下并非严格要求,但对于良好的主键是良好的做法:

  • 主键不应该更改
  • 不应回收主键

出于这个原因,主键不应该有任何实际意义,因此永远不应该有理由改变或重用它。因此,主键通常是任意代码,其唯一真正含义是它标识行。如果密钥纯粹用于​​识别并且没有其他含义,则通常将其称为代理密钥。

您可以付出一些努力来生成任意代码。有时他们会遵循复杂的模式,可用于检查其有效性。

如果您想采用更加懒惰的方法,可以使用序列号。与我之前的建议相反,它确实有一个含义:它是严格顺序的,因此您可以了解哪一行是在另一行之后添加的,但不是确切的时间。然而,这个事实不会改变 - 它不会改变价值,也不会被重用 - 所以它仍然相当稳定。

事实上,标识列是序列号。它是自动生成的,如果您想要主键的任意代码,它将非常有用。不幸的是,移动标准非常缓慢,所以每个DBMS都有自己的非标准变体:

  • MySQL称之为AUTO_INCREMENT
  • SQLite称之为AUTOINCREMENT
  • MSSQL称之为IDENTITY()
  • MS ACCESS称之为qazxsw poi
  • PostgreSQL称之为AUTONUMBER

每个人都有自己的怪癖。

最近,(2003年,我相信)它已经以下列形式添加到标准中:

SERIAL

但这刚刚开始出现在PostgreSQL和Oracle中。这种int generated by default as identity 的使用与微软的行为不同。

© www.soinside.com 2019 - 2024. All rights reserved.