↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

不受支持的版本: 7.2 / 7.1 / 6.5 / 6.4
历史版本PostgreSQL 7.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

7.7. 键 #

作者

由 Herouth Maoz()撰写。它最初于 1998-03-02 发表在用户邮件列表上,作为对问题“What is the difference between PRIMARY KEY and UNIQUE constraints?”的回答。

Subject: Re: [QUESTIONS] PRIMARY KEY | UNIQUE

        下面两者有什么区别:

              PRIMARY KEY(fields,...) 和
              UNIQUE (fields,...)

       - 这是一个别名吗?
       - 如果 PRIMARY KEY 已经是唯一的,那为什么
         还会有另一种名为 UNIQUE 的键?

主键是用来标识特定行的字段。例如,用社会保障号码标识一个人。

一个单纯的 UNIQUE 字段组合与标识行无关,它只是一种完整性约束。例如,我有若干链接集合。每个集合由一个唯一的编号标识,这个编号就是主键。这个键用于关系。

不过,我的应用还要求每个集合有一个唯一的名称。为什么?为了让想要修改集合的人能够识别它。如果你有两个名为“Life Science”的集合,就很难知道究竟标记为 24433 的那个才是你需要的,而标记为 29882 的那个不是。

因此,用户通过名称来选择集合。我们因而在数据库中确保名称是唯一的。但是,数据库中没有其他表通过集合名称与 collections 表关联,那样做会非常低效。

而且,集合名称尽管唯一,实际上并不定义这个集合!例如,如果有人决定把集合的名称从“Life Science”改为“Biology”,它仍然是同一个集合,只是名称不同而已。只要名称是唯一的,这就没有问题。

所以:

  • 主键:

    • 用于标识行并与其他数据相关联。

    • 不可能(或很难)更新。

    • 不应允许 NULL。

  • 唯一字段:

    • 用作访问行的另一种途径。

    • 可以更新,只要保持唯一。

    • 可以接受 NULL。

至于为什么标准 SQL 语法中没有显式定义非唯一键?你必须理解,索引是依赖于实现的。SQL 不定义实现,只定义数据库中数据之间的关系。Postgres 确实允许非唯一索引,但用于强制 SQL 键的索引总是唯一的。

因此,你可以按列的任意组合查询一个表,即使你在这些列上并没有索引。索引只是每种 RDBMS 提供给你的实现辅助手段,目的是让常用的查询执行得更高效。有些 RDBMS 还可能提供额外的手段,例如把键保存在主存中。它们会有一个特殊命令,例如

CREATE MEMSTORE ON table COLUMNS cols

(这不是一个真实存在的命令,只是一个例子。)

事实上,当你创建主键或唯一的字段组合时,SQL 规范中没有任何地方说会创建索引,也没有说按键检索数据会比顺序扫描更高效!

所以,如果你想用一个不唯一的字段组合作为辅助键,其实完全不必指定任何东西——直接按那个组合开始检索就行了!不过,如果你想让检索高效,就得求助于你的 RDBMS 供应商提供的手段——无论是索引、我虚构的 MEMSTORE 命令,还是一个智能的 RDBMS:它会根据你曾基于特定键组合发送过许多查询这一事实,在你不知情的情况下创建索引……(它从经验中学习)。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。