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开启外键",会显得你既懂原理又有实战经验~

相关推荐
骥龙20 小时前
3.10、构建网络防线:防火墙、WAF 与蜜罐实战
服务器·网络·数据库·网络安全
gugugu.1 天前
Redis 字符串类型完全指南:从原理到实战应用
数据库·redis·缓存
杨云龙UP1 天前
MySQL 自动备份与覆盖恢复实战:一套脚本搞定全库/按库备份恢复
linux·运维·数据库·sql·mysql
workflower1 天前
PostgreSQL 数据库优化
数据库·团队开发·数据库开发·时序数据库·数据库架构
计算机毕设VX:Fegn08951 天前
计算机毕业设计|基于springboot + vue服装商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·课程设计
WX-bisheyuange1 天前
基于Spring Boot的智慧校园管理系统设计与实现
java·大数据·数据库·毕业设计
JavaGuide1 天前
对标MinIO!全新一代分布式文件系统诞生!
数据库·后端
快乐非自愿1 天前
数据库如何处理大量的交易流水记录
数据库·oracle
IvorySQL1 天前
瀚高硬核助力 PG 社区:Postgres 19 迎来并行 TID 范围扫描,速度提升 3 倍
数据库·postgresql·开源
ServBay1 天前
MongoDB 的文档模型与 CRUD 实战
数据库·后端·mongodb