作者: 由 Herouth Maoz(<[email protected]>) 写作。 这些最早出现在 1998-03-02 用户邮件列表里关于"主键(PRIMARY KEY)和唯一约束(UNIQUE constraints)有什么异同"问题的解答.
Subject: Re: [QUESTIONS] PRIMARY KEY | UNIQUE
What's the difference between: (下面两者有何区别?)
PRIMARY KEY(fields,...) and
UNIQUE (fields,...)
- Is this an alias?(这是别名吗?)
- If PRIMARY KEY is already unique, then why
is there another kind of key named UNIQUE?
(如果 PRIMARY KEY 已经唯一,
那么为什么有另外一个名为 UNIQUE 类型的键字?)
主键是用于标识某特定行的字段.例如,身份证号码(社会安全号)标识一个人.
一个由字段组成的简单 UNIQUE 与行标识毫无关系. 它只是一个完整性约束.例如,我收集了一些互联网链接.每一 个互联网链接用一个唯一的数字标识,也就是主键,这个键用于表中。
但是,我的应用要求每套集合还要有一个唯一的名称. 因为这样做的话一个想更改一个互联网链接集合的"人"就可以找出 该集合.毕竟,如果你有两个集合都叫“生命科学”, 一个被标识成24433, 另一个是29882,而24433那个是你要找的, 这样找要比从拥有唯一集合名称的组中找难得多.
所以,用户用名称来选择集合.因此,对这个数据库我们确信名称是唯一的. 但是数据库中没有其他表与链接集合表通过 链接集合名称相关.因此这样做很效率很底.
另外,尽管组名称是唯一的,但它实际上并不定义集合! 例如,如果某人决定将集合名从“生命科学”改为 “生物学”, 该集合仍 然是同一集合,只是名字不同而已.只要名称仍然是唯一的即可.
所以:
主键:
用于标识某行而且与之相关.
是不可能(或很难)更新.
不应该允许空(NULL).
唯一域/字段:
用于作为访问某行的可选手段.
只要唯一就可以更新.
可以为空(NULLs).
那么为什么标准 SQL 语法里没有非唯一键的明确定义呢? 这是因为索引是与具体实现相关的. SQL 不定义实现,只定义 数据库内数据间的关系, Postgres 的确允许非唯一索引,但是用于增强 SQL 键字的索引总是唯一的.
因此,你可以通过任何表中的列的组合来查询该表, 不管你是否在这些列上建立了索引.索引只是每个 RDBMS 的实现 提供给你的一个工具,以便令常用的查询可以更有效的进行.有些 RDBMS 可能会给你另外一些工具,例如在主存里保 留一个键值.它们有一些特殊的命令,例如
CREATE MEMSTORE ON table COLUMNS cols(这不是一个实际的命令,只是一个例子).
实际上,当你创建一个主键或一个域/字段的唯一组合时,在 SQL 声明中没有任何地方提到创建了索引, 用该键对数据的 检索也不会比一次顺序搜索更高效!
所以,如果你想用一个并不唯一的字段组合作为从键字, 你实际上不用声明任何东西 - 只要用那个组合检索就行了. 但是,如果你想令检索更高效一些,你就不得不依赖你的 RDBMS 提供者给你的工具-不管是索引还是我想象的那种 MEMSTORE 命令或是一个智能的 RDBMS , 它在你还没有意识到你常用一套特定的键字组合来查询时就给你创建了索 引... (它从经验中学来)。