MYSQL-外键(Foreign Key)

作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。

MySQL**(本章节)**

PostgreSQL

MongoDB

Redis

Etcd

我们来深入探讨 MySQL 中的外键(Foreign Key) 。外键是关系型数据库的基石,用于强制保持数据之间的参照完整性(Referential Integrity)

一、外键是什么?

外键 是表中的一个或多个字段,其值必须与另一张表(或本表)的主键(Primary Key)唯一键(Unique Key) 的值相匹配。

它建立了两张表之间的一种"从属"或"关联"关系。

  • 主表(被引用表,Parent Table):包含被引用的主键或唯一键的表。

  • 从表(引用表,Child Table):包含外键的表。

简单比喻

  • department 表(主表)有 id (主键) 和 name 字段。

  • employee 表(从表)有 id, name, 和 dept_id 字段。

  • 这里的 dept_id 就是一个外键,它引用了 department 表的 id 字段。它保证了每个员工所属的部门一定是在 department 表中真实存在的。

二、外键的核心作用:参照完整性

外键的核心目的不是为了提高查询性能(事实上,它有时会降低性能),而是为了强制维护数据之间的逻辑关系,防止"孤立数据"和"无效数据"的出现。

没有外键约束时,可能会发生:

  1. employee 表中插入一个 dept_id = 999 的员工,但 department 表中根本不存在 id = 999 的部门。这个员工就成了"孤儿数据"。

  2. department 表中删除一个正在被 employee 表引用的部门,导致大量员工指向一个不存在的部门。

外键约束可以自动防止上述情况发生。

三、外键约束的规则与引用操作

当你定义外键时,可以指定当主表中的数据被更新(UPDATE)或删除(DELETE)时,对从表中的数据应该执行什么操作。这是外键最强大的功能所在。

以下是主要的引用操作:

1. RESTRICT / NO ACTION(默认行为)

  • 含义拒绝操作。如果从表中存在与之关联的记录,MySQL 会拒绝删除或更新主表中的这条记录。

  • 示例:尝试删除一个还有员工的部门,操作会被直接拒绝并报错。

2. CASCADE(级联操作)

  • 含义同步操作。对主表的主键进行操作时,会自动同步到从表的外键上。

  • ON DELETE CASCADE:删除主表中的记录时,自动删除从表中所有相关联的记录。

  • ON UPDATE CASCADE:更新主表主键的值时,自动更新从表中所有相关外键的值。

  • 示例ON DELETE CASCADE 设定后,删除一个部门,该部门下的所有员工记录也会被自动删除。此操作非常危险,需谨慎使用!

3. SET NULL

  • 含义设置为空 。如果主表中的记录被删除或更新,则将从表中相关记录的外键值设置为 NULL

  • 前提 :从表的外键字段必须允许为 NULL

  • 示例 :删除一个部门后,将该部门所有员工的 dept_id 字段自动设为 NULL,表示这些员工暂时"未分配部门"。

4. SET DEFAULT

  • 含义设置为默认值。将外键值设置为该列的默认值。

  • 注意InnoDB 存储引擎不支持此操作

四、外键的案例

创建主表

sql 复制代码
CREATE TABLE departments (
    department_id INT PRIMARY KEY AUTO_INCREMENT,
    department_name VARCHAR(100) NOT NULL
);

创建引用表

sql 复制代码
CREATE TABLE employees (
    employee_id INT PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    department_id INT,
    -- 定义外键约束
    FOREIGN KEY (department_id) 
        REFERENCES departments(department_id)
        ON DELETE SET NULL
        ON UPDATE CASCADE
);

外键语法

  • FOREIGN KEY (department_id):指定当前表中的哪个字段是外键

  • REFERENCES departments(department_id):指定外键引用哪个表的哪个字段

  • ON DELETE SET NULL:当被引用的部门被删除时,将此字段设为 NULL

  • ON UPDATE CASCADE:当被引用的部门ID更新时,自动更新所有相关的员工记录

运维小路

一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!

关注微信公众号《运维小路》获取更多内容。

相关推荐
Yana.nice5 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
Database_Cool_6 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
Database_Cool_7 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
2601_960567967 小时前
电商套图自动化效率的工程量化分析——从逐张生成到批量套图的架构演进
运维·架构·自动化
姜太小白8 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
吳所畏惧8 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈8 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HiDev_9 小时前
【非标自动化】2、认识元器件(确定目标)
运维·自动化
liuxiaowei39 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
Zhang~Ling9 小时前
从 fopen 到 struct file:从零开始拆解 Linux 文件 I/O
linux·运维·服务器