首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >唯一键与主键的区别

唯一键与主键的区别
EN

Stack Overflow用户
提问于 2011-06-17 07:54:20
回答 5查看 14.4K关注 0票数 12

我在一本书中偶然发现了以下SQL:

代码语言:javascript
复制
CREATE TABLE 'categories'(
id SMALLINT NOT NULL AUTO INCREMENT,
category VARCHAR(30) NOT NULL,
PRIMARY KEY('id'),
UNIQUE KEY 'category'('category')
)ENGINE=MyISAM DEFAULT CHARSET = utf8;

我想知道为什么我在同一个表中需要一个主键和唯一键?我想,这个问题背后的问题是,主键和唯一键之间的区别是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-17 08:16:49

关系模型表明,一个键和另一个键之间没有本质区别。也就是说,当关系有多个候选关键字时,理论上没有理由声明这个关键字比那个关键字更重要。从本质上讲,这意味着在理论上没有理由将一个键标识为主键,而将所有其他键标识为辅键。(不过,这可能有实际的原因。)

许多关系都有多个候选键。例如,美国各州的关系可能有这样的数据。

代码语言:javascript
复制
State      Abbr      Postal Code
--
Alabama    Ala.      AL
Alaska     Alaska    AK
Arizona    Ariz.     AZ
...
Wyoming    Wyo.      WY

很明显,这三列中的每一列中的值都是唯一的--有三个候选键。

如果您打算在SQL中构建一个表来存储这些值,您可以这样做。

代码语言:javascript
复制
CREATE TABLE states (
  state varchar(15) primary key,
  abbr varchar(10) not null unique,
  postal_code char(2) not null unique
);

您会这样做,因为SQL没有任何其他方式来表示“我的表有三个独立的候选键”。

我没有任何特别的理由选择"state“作为主键。我可以很容易地选择"abbr“或"postal_code”。这三列中的任何一列也可以用作外键引用的目标。

到目前为止,我也可以像这样构建这个表。

代码语言:javascript
复制
CREATE TABLE states (
  state varchar(15) not null unique,
  abbr varchar(10) not null unique,
  postal_code char(2) not null unique
);
票数 20
EN

Stack Overflow用户

发布于 2011-06-17 08:17:56

我很惊讶,没有人提到主键可以作为外键引用到其他表中。

此外,唯一约束允许空值。

票数 8
EN

Stack Overflow用户

发布于 2011-06-17 08:13:37

您需要两个唯一性限制(其中一个是主键)的原因是您使用Id作为代理键。也就是说,它是一个任意值,对于数据本身没有任何意义。如果没有唯一键(或者俗称为“业务键”,即用户会认为是强制执行的键),用户可以添加具有不同任意ID值的两个相同的category值。因为用户永远不会看到代理键,所以即使数据库认为它们是不同的,他们也不会知道为什么会看到重复的项。

在使用代理键时,对代理键以外的其他内容具有另一个唯一约束对于避免重复数据至关重要。

根据您与谁交谈以及他们如何阅读规范,唯一的密钥(顺便说一句,这是多余的。"key“根据定义是唯一的)也不应该允许空值。然而,人们也可以将规范理解为唯一约束,不同于主键约束,实际上应该允许空值(允许多少空值也因供应商而异)。大多数产品,包括MySQL,都允许唯一约束中的空值,而主键约束不允许。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6379954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档