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

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

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

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

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

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

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

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

相关推荐
IvorySQL9 小时前
PostgreSQL 日报|修复截断 zstd 备份检测(10 月 9 日)
数据库·postgresql
刘胡子大叔10 小时前
SQL 脚本的导入顺序
数据库·sql
代码什么用10 小时前
Spring对IoC的实现
数据库·spring
hz5678912 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC12 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
程序员Sunday12 小时前
MySQL 为什么使用 B+ 树索引?把范围查询、回表和覆盖索引连起来
数据库·mysql
半杯咖啡半行码13 小时前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
小米里的大麦13 小时前
16 MySQL 事务
数据库·mysql
西柚小萌新13 小时前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库
邓工说电14 小时前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技