【问题标题】:What is the difference between a primary key and a unique constraint?主键和唯一约束有什么区别?
【发布时间】:2009-08-20 20:22:33
【问题描述】:

有人在面试时问过我这个问题...

【问题讨论】:

标签: sql primary-key


【解决方案1】:

主键不能为空。唯一键可以。

【讨论】:

  • +1 这是关键的区别。这意味着主键中的列可以明确地处理每一行,但列唯一键不能(除非它们巧合地不为空)。
  • 阅读这个问题 (stackoverflow.com/questions/767657/…) 和答案,看起来唯一约束不能有空值。所以,我很困惑。这是特定于 MSSQL 还是什么?
【解决方案2】:

主键表上的一个唯一字段,但它的特殊之处在于表将该行视为其键。这意味着其他表可以使用该字段与自己创建外键关系。

唯一约束只是意味着特定字段必须是唯一的。

【讨论】:

  • 行的主键是数据库识别单个行的方式。它可以由一列或多列组成,它们一起也必须是唯一的。
  • 主键是一组字段,不一定是单个字段。
  • 唯一约束也可能适用于字段组合。
  • 外键也可以引用唯一约束中的列。
  • 它是旧的方形矩形规则。主键是唯一约束,但唯一约束不是主键。此外,在唯一约束可能为 null 的情况下,根据定义,PK 不能为 null。
【解决方案3】:
  1. 主键不能为空,但唯一键只能有一个空值。
  2. 主键会自动创建集群索引,但唯一键不会。
  3. 一张表只能有一个主键,但唯一键不止一个。

【讨论】:

  • +1 好答案。请注意,您的第一点适用于 SQL Server,但不适用于 MySQL。
  • 关于 SQL 标准,您的第一点不正确,第二点与 SQL 标准无关(但两者都适用于 SQL Server)。
【解决方案4】:

TL;DR PRIMARY KEY 可以暗示很多东西(唯一性、可引用性、非空性、聚类等),但没有任何东西不能使用 UNIQUE 明确说明。

我建议,如果您是那种喜欢 SELECT * FROM... 的便利而又不必列出所有那些讨厌的列的编码人员,那么 PRIMARY KEY 就是您的最佳选择。


一个 relvar 可以有多个键,但我们只选择一个作为下划线 并将其称为主键。选择是任意的,所以 从逻辑的角度来看,初级的概念并不是很重要 观点。然而,密钥的一般概念非常重要!这 术语候选键的含义与键完全相同(即,加法 候选人没有实际意义——它是由 Ted Codd 提出的 因为他把每把钥匙都看作是被提名为 主键)... SQL 允许表列的子集 声明为该表的键。它还允许其中一个成为 指定为主键。指定一个键作为主键 为了与其他相关的一定程度的方便 可能需要的约束

What Is a Key? by Hugh Darwen


通常...选择一个键作为主键(以及任何其他键) 然后将相关 relvar 的键称为备用键)。 但是是否要选择某个键作为主键,如果选择是哪个键, 本质上是心理问题,超出了 关系模型之类的。作为一种良好的做法,大多数基地 relvars 可能应该有一个主键——但是,重复一遍,这条规则, 如果这是一个规则,那么真的不是一个关系问题......强 推荐 [给 SQL 用户]:对于基表,无论如何,使用 主键和/或唯一规范,以确保每一个这样的 表确实至少有一个键。

SQL and Relational Theory: How to Write Accurate SQL Code 作者:C.J. 日期

在标准 SQL 中PRIMARY KEY

  • 暗示唯一性,但您可以明确指定(使用UNIQUE)。
  • 隐含NOT NULL,但您可以在创建列时明确指定(但无论如何您都应该避免空值!)
  • 允许您在 FOREIGN KEY 中省略其列,但您可以明确指定它们。
  • 可以为每个表只声明一个键,但不清楚原因(最初提出该概念的 Codd 没有施加这样的限制)。

在某些产品中,PRIMARY KEY 暗示表的聚集索引,但您可以明确指定(您可能不希望主键成为聚集索引!)

对于某些人PRIMARY KEY具有纯粹的心理意义:

  • 他们认为这表示该键将在外键中引用(这是 Codd 提出的,但标准 SQL 和 SQL 供应商并未实际采用)。
  • 他们认为它表示表的唯一键(但未能强制执行其他候选键会导致数据完整性丢失)。
  • 他们认为这意味着“替代”或“人工”密钥对业务没有意义(但实际上通过暴露给用户对企业施加了不必要的意义)。

【讨论】:

  • 如果未定义为 NOT NULL,则 UNIQUE 列中可以有 1 个 NULL 值,但 PRIMARY KEY 列中不能有任何 NULL
【解决方案5】:

每个主键都是唯一约束,但除了 PK,表还可以有其他唯一约束。

假设您有一个员工表,PK EmployeeID。例如,您可以在 SSN 上添加唯一约束。

【讨论】:

    【解决方案6】:

    唯一键约束:

    1. 唯一键约束将为您提供一个约束,例如列值应保持唯一性。
    2. 默认会创建非聚集索引
    3. 可以向表中添加任意数量的唯一约束。
    4. 它将允许列中的空值。

      ALTER TABLE 表名 添加约束 UNIQUE_CONSTRAINT 唯一(column_name1,column_name2,...)

    主键:

    1. 主键将在表中创建列数据唯一性。
    2. 主键默认创建聚集索引
    3. 只能为一个表创建一个 Primay 键
    4. 可以合并多个列以形成一个主键
    5. 它不允许空值。

      ALTER TABLE 表名 添加约束 KEY_CONSTRAINT 主键(列名)

    【讨论】:

    • 主关键点 4:UNIQUE 约束可以是简单键或复合键(简单 = 一列,复合 = 多列),即在这方面与 PRIMARY KEY 没有区别。
    【解决方案7】:

    除了 Andrew 的回答,每个表只能有一个主键,但可以有许多唯一约束。

    【讨论】:

    • 可以有多个主键,称为复合键。
    • 从技术上讲,您可以拥有一个由多个字段组成的主键,但您仍然只能拥有一个整体主键。
    【解决方案8】:
    1. 主键的目的是唯一标识表中的一行。唯一约束确保字段的值在表中的行中是唯一的。
    2. 每个表只能有一个主键。每个表可以有多个唯一约束。

    【讨论】:

      【解决方案9】:

      主键是一组最小的列,这样在这些列中具有相同值的任何两条记录在所有列中都具有相同的值。请注意,一个主键可以由多个列组成。

      唯一性约束正是它听起来的样子。

      【讨论】:

      • @Thom 您的措辞听起来像是唯一性约束只能应用于单个列,这是不正确的。
      【解决方案10】:

      UNIQUE 约束唯一标识数据库表中的每条记录。

      UNIQUE 和 PRIMARY KEY 约束都为一列或一组列提供唯一性保证。

      PRIMARY KEY 约束自动定义了一个 UNIQUE 约束。

      请注意,每个表可以有许多 UNIQUE 约束,但每个表只能有一个 PRIMARY KEY 约束

      【讨论】:

        【解决方案11】:

        主键不能为空,但唯一约束可以为空。 当您为表选择主键时,它会自动索引该字段。

        【讨论】:

          【解决方案12】:

          主键本质上是 (unique +not null) 的组合。在引用外键时,rdbms 也需要主键。

          唯一键只是强加列的唯一性。在唯一键的情况下,字段的值可以为 NULL。它也不能用于引用外键,这很明显,因为你可以在其中包含空值

          【讨论】:

          • 不,外键也可以引用唯一约束中的列。
          【解决方案13】:

          两者都保证表中各行的唯一性,但其他一些答案中提到的空值除外。

          此外,主键“附带”一个索引,该索引可以是聚簇或非聚簇。

          【讨论】:

          • 许多 RDBMS 会自动为唯一约束创建索引。 (我不知道有什么不知道的。)
          【解决方案14】:

          到目前为止,这里有几个很好的答案。除了主键不能为空、本身是唯一约束、可以由多列组成之外,还有更深层次的含义取决于您使用的数据库服务器。

          我是 SQL Server 用户,因此主键对我来说具有更具体的含义。在 SQL Server 中,默认情况下,主键也是所谓的“聚集索引”的一部分。聚集索引定义了该特定表的数据页的实际顺序,这意味着主键顺序与磁盘上行的物理顺序相匹配。

          我知道 MySql 的一种(可能更多)表格式也支持聚集索引,这意味着它在 SQL Server 中所做的事情......它定义了磁盘上的物理行顺序。

          Oracle 提供了一种称为索引组织表的东西,它按主键对磁盘上的行进行排序。

          我对 DB2 不是很熟悉,但是我认为聚集索引意味着磁盘上的行与单独的索引以相同的顺序存储。我不知道聚集索引是否必须与主键匹配,或者它是否可以是一个不同的索引。

          【讨论】:

          • Oracle 有索引组织表,类似于 SQL Server 聚集索引,只是排序是在主键上,而 SQL Server 的聚集索引是在其他索引上。
          • @Shannon:在 SQL Server 中,聚集索引是磁盘上的一组物理页,就像 Oracle 索引组织表一样。聚集索引没有单独的索引……但是 SQL Server 中的聚集索引不必是主键索引。默认情况下,创建表以在主键上进行聚类,但不限于按主键进行聚类。
          【解决方案15】:

          这里的很多答案都讨论了 PK 与唯一约束的属性。但更重要的是理解概念上的差异。

          主键被认为是数据库中记录的标识符。因此,例如在创建表之间的外键引用时会引用这些。因此,在正常情况下,主键不应包含在您的域中具有任何意义的值(通常自动递增字段用于此目的)。

          唯一约束只是在您的数据库架构中执行特定领域业务规则的一种方式。

          因为 PK 是记录的标识符,所以您永远不能更改主键的值。

          【讨论】:

          • +1 看看这个方面也很好。但是您的最后一句话并不完全正确:Becuase a PK it is an identifier for the record, you can never change the value of a primary key.您可能不应该更改主键,但您可以做到。
          • -1 “因此,在正常情况下,主键不应包含在您的域中具有任何意义的值”——这是事实。
          猜你喜欢
          • 1970-01-01
          • 2013-12-22
          • 1970-01-01
          • 2016-09-20
          • 1970-01-01
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多