目录
[1. 确定"父表"和"子表"](#1. 确定“父表”和“子表”)
[2. 外键的核心作用:拦截"无效关联"](#2. 外键的核心作用:拦截“无效关联”)
[关键:外键动作(ON DELETE / ON UPDATE)怎么用?](#关键:外键动作(ON DELETE / ON UPDATE)怎么用?)
先看一个没有外键的"混乱场景"
假设公司有两张表:
- 
Departments(部门表):存部门ID和部门名(比如研发部、市场部);
- 
Employees(员工表):存员工ID、姓名、所属部门ID。
如果没有外键约束,会出现这些问题:
- 
员工属于"不存在的部门" :比如员工表中存了 dept_id=99,但部门表中根本没有99号部门,这个员工就成了"无所属部门的幽灵员工";
- 
删除部门后,员工信息成垃圾 :比如研发部( dept_id=1)被删除了,但员工表中还有很多dept_id=1的员工,这些员工的部门信息永远无效了;
- 
部门ID改了,员工信息没同步 :比如研发部ID从1改成100,但员工表中还是 dept_id=1,导致所有研发部员工"找不到部门"。
外键约束的作用,就是通过规则避免这些混乱,保证"部门"和"员工"的关联永远有效。
外键约束:给表之间加"联动规则"
以上面的部门和员工表为例,外键约束会这样工作:
1. 确定"父表"和"子表"
- 
父表: Departments(部门是"主",员工依赖部门存在);
- 
子表: Employees(员工是"从",所属部门必须在父表中存在);
- 
外键列:员工表的 dept_id(这个值必须对应父表Departments的dept_id)。
创建表时定义外键:
-- 父表:部门表(有主键dept_id)
CREATE TABLE Departments (
    dept_id INTEGER PRIMARY KEY,
    dept_name TEXT NOT NULL -- 部门名不能为空
);
-- 子表:员工表(外键关联部门表)
CREATE TABLE Employees (
    emp_id INTEGER PRIMARY KEY,
    name TEXT,
    dept_id INTEGER, -- 外键列:关联部门ID
    -- 外键约束:员工的dept_id必须在Departments表的dept_id中存在
    FOREIGN KEY (dept_id) REFERENCES Departments (dept_id)
        ON DELETE SET NULL  -- 部门删除时,员工的dept_id设为NULL
        ON UPDATE CASCADE   -- 部门ID更新时,员工的dept_id同步更新
);2. 外键的核心作用:拦截"无效关联"
- 
当你想往员工表插入 dept_id=99(但部门表没有99)时,数据库会直接报错,拒绝插入------避免"幽灵员工";
- 
当你想删除部门表中 dept_id=1(但员工表还有人属于这个部门)时,外键会按规则处理(比如上面的ON DELETE SET NULL会把员工的dept_id改成NULL,而不是允许删除后留垃圾数据)。
关键:外键动作(ON DELETE / ON UPDATE)怎么用?
这是面试高频考点,结合场景理解四种常用规则:
| 动作 | 场景举例(部门表操作后,员工表如何联动) | 
|---|---|
| RESTRICT(默认) | 如果研发部(dept_id=1)还有员工,就禁止删除研发部("先清员工,才能删部门")。适合不允许"部门下有员工时删部门"的场景(比如重要部门)。 | 
| SET NULL | 研发部被删除后,所有原研发部员工的 dept_id变成NULL("部门没了,员工暂归无部门")。适合部门可删除,但员工信息需保留的场景。 | 
| CASCADE | 研发部ID从1改成100 → 所有员工的 dept_id自动从1改成100;删除研发部 → 所有研发部员工也被删除("部门没了,员工也一起清")。适合临时项目部门(项目结束,部门和员工记录一起删)。 | 
| SET DEFAULT | 提前给员工表的 dept_id设默认值(比如0代表"待分配"),删除部门后,员工dept_id自动变成0。适合需要明确"无部门员工归到默认组"的场景。 | 
面试必知:SQLite外键需要手动启用!
和其他数据库(如MySQL)不同,SQLite的外键约束默认可能关闭(尤其是旧版本)。所以在连接数据库后,必须先执行一句命令开启外键:
PRAGMA foreign_keys = ON; -- 开启外键约束(关键!面试说出来加分)如果没开,外键约束会失效,上面的所有规则都不会生效(这是很多人踩过的坑)。
总结:外键是"表关系的守护神"
它通过三个层面保证数据有效:
- 
插入时:子表不能引用父表不存在的数据(拦截幽灵员工); 
- 
删除时:按规则处理子表关联数据(避免垃圾数据); 
- 
更新时:同步子表关联字段(避免关联断裂)。 
面试时结合"部门-员工""订单-商品"等场景举例,再提一句"记得用PRAGMA开启外键",会显得你既懂原理又有实战经验~