FOREIGN KEY 与引用操作
使用 FOREIGN KEY 关联表,并为正确的行为选择 ON DELETE CASCADE / SET NULL / RESTRICT。
FOREIGN KEY 与引用操作 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。
外键的作用
FOREIGN KEY 会让数据库拒绝指向不存在父行的行:
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
total NUMERIC(10,2) NOT NULL
);
-- Inserting an order with user_id=999 fails if no such user exists.为什么使用外键
FK 可以强制执行引用完整性:
- 不会出现孤立行
- 在插入时捕获应用错误
- 使 ER 图保持准确
- 支持自动级联行为
引用操作
删除或更新父行时应该发生什么?有五种选项:
NO ACTION— 报错(默认,可延迟)RESTRICT— 报错(不可延迟)CASCADE— 同时删除或更新子行SET NULL— 将子行的 FK 设置为 NULLSET DEFAULT— 将子行的 FK 设置为其默认值
ON DELETE CASCADE
“删除用户时,也删除其订单”:
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL
REFERENCES users(id) ON DELETE CASCADE,
total NUMERIC(10,2) NOT NULL
);ON DELETE SET NULL
“删除经理时,员工仍然存在,但不再拥有经理”:
CREATE TABLE employees (
id BIGSERIAL PRIMARY KEY,
full_name TEXT NOT NULL,
manager_id BIGINT REFERENCES employees(id) ON DELETE SET NULL
);默认行为:类似 RESTRICT
没有引用操作时,尝试删除带有子行的父行会失败:
ERROR: update or delete on table "users" violates foreign key constraint "orders_user_id_fkey" on table "orders"
DETAIL: Key (id)=(42) is still referenced from table "orders".始终为 FK 列创建索引
PostgreSQL 不会自动在子表一侧创建索引。请添加索引——否则删除父行时会触发对每个子表的完整扫描:
CREATE INDEX orders_user_id_idx ON orders(user_id);复合外键
引用复合主键:
CREATE TABLE order_items (
order_id BIGINT,
line_no INT,
PRIMARY KEY (order_id, line_no)
);
CREATE TABLE shipments (
order_id BIGINT,
line_no INT,
FOREIGN KEY (order_id, line_no)
REFERENCES order_items(order_id, line_no)
);延迟外键检查
有时您需要插入一对互相依赖的数据。请将 FK 标记为 DEFERRABLE INITIALLY DEFERRED:
ALTER TABLE orders
ALTER CONSTRAINT orders_user_id_fkey DEFERRABLE INITIALLY DEFERRED;
BEGIN;
INSERT INTO orders ... ; -- FK temporarily not checked
INSERT INTO users ... ;
COMMIT; -- checked here在线添加外键
对于大型表,请使用 NOT VALID + VALIDATE,以避免长时间锁定:
ALTER TABLE orders
ADD CONSTRAINT orders_user_id_fkey
FOREIGN KEY (user_id) REFERENCES users(id) NOT VALID;
ALTER TABLE orders VALIDATE CONSTRAINT orders_user_id_fkey;谨慎使用级联
CASCADE 会传播删除操作。删除一个用户可能会清除订单、付款记录和审计日志。请确保级联行为符合您的业务意图。
回顾
外键就像护栏。
- REFERENCES + 操作声明关联关系及其行为
- 在子表一侧为 FK 列创建索引
- 使用 NOT VALID + VALIDATE 在线添加外键
快速检查
当父用户被删除时,要 AUTOMATICALLY 删除其订单,正确的引用操作是什么?
常见问题解答
「FOREIGN KEY 与引用操作」课时是免费的吗?
是的 — 「FOREIGN KEY 与引用操作」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。
「FOREIGN KEY 与引用操作」这节课中我会学到什么?
使用 FOREIGN KEY 关联表,并为正确的行为选择 ON DELETE CASCADE / SET NULL / RESTRICT。 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 SQL Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「FOREIGN KEY 与引用操作」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 SQL Academy 课中编写并运行代码吗?
能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- NOT NULL 与 CHECK 约束
- UNIQUE 约束与复合键
- FOREIGN KEY 与引用操作
- DEFAULT 值与生成列