0Pricing
SQL Academy · 课时

主键与唯一性

理解主键、代理键与自然键、复合键,以及为何每一行都需要一个值得信赖的唯一标识符。

主键与唯一性 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

为什么每一行都需要唯一 ID

要安全地更新或删除特定行,您必须能够明确无误地定位它。

  • 可以存在两个名为 "Alice Adams" 的用户
  • 但不能存在两个 id = 42 的用户
  • 这个唯一标识符称为主键

声明主键

创建表时,您可以将某一列标记为主键:

CREATE TABLE products (
  id    BIGSERIAL PRIMARY KEY,
  sku   VARCHAR(50) NOT NULL,
  name  VARCHAR(200) NOT NULL,
  price NUMERIC(10,2) NOT NULL
);

主键 = NOT NULL + UNIQUE

PRIMARY KEY 会自动强制执行以下规则:

  • NOT NULL——主键值不能缺失
  • UNIQUE——不能有两行共享相同的主键值

数据库还会在主键上创建唯一索引,因此按 ID 查找的速度很快。

代理键与自然键

对于主键,您有两种选择:

  • 代理键——由数据库生成的合成 ID(BIGSERIAL、UUID)。现代应用中最常见。
  • 自然键——现实世界中的标识符(电子邮件、ISBN)。存在风险:人们可能会更换电子邮件地址。

最佳实践是:使用代理 ID,并在自然键上添加 UNIQUE 约束。

BIGSERIAL:自动递增整数

在 PostgreSQL 中,BIGSERIAL 会创建一个由序列支持的 64 位自动递增列。

CREATE TABLE orders (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT NOT NULL,
  total NUMERIC(10,2) NOT NULL
);

-- You omit id on insert and the DB fills it in:
INSERT INTO orders (user_id, total) VALUES (7, 99.50);

UUID 主键

另一种选择是 128 位 UUID,适用于 ID 必须在不同系统之间保持唯一,或需要在客户端生成的情况。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE sessions (
  id    UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id BIGINT NOT NULL,
  ip    INET
);

复合主键

有时,自然标识符是多个列的组合:

CREATE TABLE order_items (
  order_id  BIGINT NOT NULL,
  product_id BIGINT NOT NULL,
  quantity  INT NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

-- The pair (order_id, product_id) must be unique
-- A product can appear at most once per order

UNIQUE 约束与主键的区别

您可以将其他列声明为唯一列,而不将它们设为主键:

CREATE TABLE users (
  id    BIGSERIAL PRIMARY KEY,
  email VARCHAR(255) NOT NULL UNIQUE,
  username VARCHAR(50) UNIQUE
);

-- INSERT below fails on the second row:
INSERT INTO users (email, username) VALUES ('a@x.com', 'alice');
INSERT INTO users (email, username) VALUES ('a@x.com', 'bob');  -- ERROR

插入重复项时会发生什么

如果您尝试插入重复的主键,数据库会拒绝整个语句:

ERROR:  duplicate key value violates unique constraint "users_pkey"
DETAIL:  Key (id)=(42) already exists.

这是一件好事——它可以阻止数据在不知不觉中损坏。

按主键查找行的速度很快

主键上的唯一索引可以提供 O(log n) 的查找速度,即使数据规模达到十亿行也是如此。

-- Index Scan using users_pkey on users (cost=0.43..8.45 rows=1)
SELECT email FROM users WHERE id = 42;

不要重复使用 ID

即使您删除了一行,也不要重复使用它的主键。其他表或外部系统可能仍然引用它。让序列继续递增即可——ID 的成本很低。

总结

主键为每一行提供稳定且唯一的标识。

  • 优先使用代理键(BIGSERIAL 或 UUID)
  • 对于不能重复的自然键,使用 UNIQUE
  • 复合主键可以表示“这一对值必须唯一”

快速检查

下面哪项会由 PRIMARY KEY 隐式强制执行?

常见问题解答

「主键与唯一性」课时是免费的吗?

是的 — 「主键与唯一性」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「主键与唯一性」这节课中我会学到什么?

理解主键、代理键与自然键、复合键,以及为何每一行都需要一个值得信赖的唯一标识符。 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「主键与唯一性」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 什么是 RDBMS,以及表为何重要
  2. 主键与唯一性
  3. NULL:第三种真值
  4. 数据类型概览:INT VARCHAR DATE BOOLEAN
← 返回 SQL Academy