SQlite:外键约束

目录

先看一个没有外键的"混乱场景"

外键约束:给表之间加"联动规则"

[1. 确定"父表"和"子表"](#1. 确定“父表”和“子表”)

[2. 外键的核心作用:拦截"无效关联"](#2. 外键的核心作用:拦截“无效关联”)

[关键:外键动作(ON DELETE / ON UPDATE)怎么用?](#关键:外键动作(ON DELETE / ON UPDATE)怎么用?)

面试必知:SQLite外键需要手动启用!

总结:外键是"表关系的守护神"


先看一个没有外键的"混乱场景"

假设公司有两张表:

  • Departments(部门表):存部门ID和部门名(比如研发部、市场部);

  • Employees(员工表):存员工ID、姓名、所属部门ID。

如果没有外键约束,会出现这些问题:

  1. 员工属于"不存在的部门" :比如员工表中存了dept_id=99,但部门表中根本没有99号部门,这个员工就成了"无所属部门的幽灵员工";

  2. 删除部门后,员工信息成垃圾 :比如研发部(dept_id=1)被删除了,但员工表中还有很多dept_id=1的员工,这些员工的部门信息永远无效了;

  3. 部门ID改了,员工信息没同步 :比如研发部ID从1改成100,但员工表中还是dept_id=1,导致所有研发部员工"找不到部门"。

外键约束的作用,就是通过规则避免这些混乱,保证"部门"和"员工"的关联永远有效。

外键约束:给表之间加"联动规则"

以上面的部门和员工表为例,外键约束会这样工作:

1. 确定"父表"和"子表"
  • 父表:Departments(部门是"主",员工依赖部门存在);

  • 子表:Employees(员工是"从",所属部门必须在父表中存在);

  • 外键列:员工表的dept_id(这个值必须对应父表Departmentsdept_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; -- 开启外键约束(关键!面试说出来加分)

如果没开,外键约束会失效,上面的所有规则都不会生效(这是很多人踩过的坑)。

总结:外键是"表关系的守护神"

它通过三个层面保证数据有效:

  1. 插入时:子表不能引用父表不存在的数据(拦截幽灵员工);

  2. 删除时:按规则处理子表关联数据(避免垃圾数据);

  3. 更新时:同步子表关联字段(避免关联断裂)。

面试时结合"部门-员工""订单-商品"等场景举例,再提一句"记得用PRAGMA开启外键",会显得你既懂原理又有实战经验~

相关推荐
TDengine (老段)19 小时前
TDengine 生态系统连接指南
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
k***921619 小时前
C++:继承
java·数据库·c++
一只旭宝19 小时前
Linux专题十二:mysql数据库以及redis数据库
linux·数据库·mysql
萧曵 丶19 小时前
MySQL B+树详解
数据库·b树·mysql
鱼跃鹰飞20 小时前
面试题:Spring事务失效的八大场景
数据库·mysql·spring
ss27320 小时前
类的线程安全:多线程编程-银行转账系统:如果两个线程同时修改同一个账户余额,没有适当的保护机制,会发生什么?
java·开发语言·数据库
郑泰科技20 小时前
windows下启动hbase的步骤
数据库·windows·hbase
子一!!20 小时前
MySQL数据库基础操作
数据库·mysql·oracle
DarkAthena20 小时前
【GaussDB】从 sqlplus 到 gsql:Shell 中执行 SQL 文件方案的迁移与改造
数据库·sql·oracle·gaussdb
Wpa.wk20 小时前
接口自动化 - 了解接口自动化框架RESTAssured (Java版)
java·数据库·自动化