MySQL外键类型与应用场景总结:优缺点一目了然
前言:
MySQL的外键简介:在 MySQL 中,外键 (Foreign Key) 用于建立和强制表之间的关联,确保数据的一致性和完整性。外键的作用主要是限制和维护引用完整性 (Referential Integrity)。
- 主要体现在引用操作发生变化时的处理方式(即
ON DELETE和ON UPDATE的行为)。 - 外键类型一共有四种:
RESTRICT、CASCADE、SET NULL、NO ACTION。接下来通过测试来演示各自的作用效果。
1、 外键效果演示
1.1、创建添加两张表数据
-- 创建父表
CREATE TABLE `users` (`user_id` INT NOT NULL AUTO_INCREMENT,`username` VARCHAR(255) NOT NULL,PRIMARY KEY (`user_id`)
);-- 创建子表
CREATE TABLE `orders` (`order_id` INT NOT NULL AUTO_INCREMENT,`order_date` DATE NOT NULL,`user_id` INT,PRIMARY KEY (`order_id`)
);-- 插入父表数据
INSERT INTO `users` (`username`) VALUES ('Alice');
INSERT INTO `users` (`username`) VALUES ('Bob');-- 插入子表数据
INSERT INTO `orders` (`order_date`, `user_id`) VALUES ('2024-12-25', 1);
INSERT INTO `orders` (`order_date`, `user_id`) VALUES ('2024-12-26', 2);
1.2、测试外键作用效果
1.2.1、RESTRICT
- 创建
RESTRICT外键
-- 添加外键约束到现有的子表 `orders`
ALTER TABLE `orders`
ADD CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`)
ON DELETE RESTRICT
ON UPDATE RESTRICT;
- 主表 删除和更新 已在 子表的外键中已存在 的数据
-- 删除已被引用的外键
DELETE FROM `users` WHERE `user_id` = 1-- 输出结果 --
> 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orders`, CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT)
> 查询时间: 0.013s-- 修改已被引用的外键
UPDATE `users` SET `user_id` = 3 WHERE `user_id` = 1-- 输出结果 --
> 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orders`, CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT)
> 查询时间: 0.009s
- 查看子表变化

– 因为删除和更新都执行失败,所以子表没有变化。
总结:RESTRICT类型的外键,如果该记录在子表中有引用,禁止删除或更新父表中的记录。
1.2.2、CASCADE
- 创建
CASCADE外键
-- 添加外键约束到 `orders` 表,使用 CASCADE
ALTER TABLE `orders`
ADD CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
- 主表 删除和更新 已在 子表的外键中已存在 的数据
-- 删除已被引用的外键
DELETE FROM `users` WHERE `user_id` = 1-- 输出结果 --
> Affected rows: 1
> 查询时间: 0.016s-- 修改已被引用的外键
UPDATE `users` SET `user_id` = 3 WHERE `user_id` = 2-- 输出结果 --
> Affected rows: 1
> 查询时间: 0.013s
- 查看子表变化

– 因为两条SQL都执行成功。
order_id = 1的数据被删除,order_id = 2的user_id的值被修改为3
总结:CASCADE类型的外键,当父表中的记录被删除或更新时,子表中的相关记录也会自动被删除或更新。
1.2.3、SET NULL
- 创建
SET NULL外键
-- 确保子表的外键列允许 NULL
ALTER TABLE `orders`
MODIFY COLUMN `user_id` INT NULL;-- 添加外键约束到 `orders` 表,使用 SET NULL
ALTER TABLE `orders`
ADD CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`)
ON DELETE SET NULL
ON UPDATE SET NULL;
- 主表 删除和更新 已在 子表的外键中已存在 的数据
-- 删除已被引用的外键
DELETE FROM `users` WHERE `user_id` = 1-- 输出结果 --
> Affected rows: 1
> 查询时间: 0.014s-- 修改已被引用的外键
UPDATE `users` SET `user_id` = 3 WHERE `user_id` = 2-- 输出结果 --
> Affected rows: 1
> 查询时间: 0.012s
- 查看子表变化

– 两条SQL都执行成功。
order_id = 1的user_id的值变为NULL,order_id = 2的user_id的值变为NULL,
总结:SET NULL类型的外键,当父表记录被删除或更新时,子表中对应的外键值会更新为NULL。
1.2.4、NO ACTION
- 创建
NO ACTION外键
-- 添加外键约束,使用 NO ACTION
ALTER TABLE `orders`
ADD CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
- 主表 删除和更新 已在 子表的外键中已存在 的数据
-- 删除已被引用的外键
DELETE FROM `users` WHERE `user_id` = 1-- 输出结果 --
> 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orders`, CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`))
> 查询时间: 0.013s-- 修改已被引用的外键
UPDATE `users` SET `user_id` = 3 WHERE `user_id` = 2-- 输出结果 --
> 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orders`, CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`))
> 查询时间: 0.025s
- 查看子表变化

– 因为删除和更新都执行失败,所以子表没有变化。
总结:NO ACTION类型的外键(和RESTRICT的作用相同),如果该记录在子表中有引用,禁止删除或更新父表中的记录。
1.3、外键作用描述以及优缺点总结
1.3.1、RESTRICT
- 描述:即父表记录在被子表引用时,无法被删除或更新。
- 适用场景:适合需要严格控制父表记录操作的场景。
- 优点:防止意外的数据丢失。
- 缺点:增加操作复杂性。
1.3.2、CASCADE
- 描述:级联操作。当父表中的记录被删除或更新时,子表中的相关记录也会自动被删除或更新。
- 适用场景:当子表记录与父表记录绑定紧密时,例如订单表和订单明细表。
- 优点:简化了复杂的删除或更新操作,自动维护数据一致性。
- 缺点:操作不当可能导致数据大量丢失或被误修改。
1.3.3、SET NULL
- 描述:当父表记录被删除或更新时,子表中对应的外键值会设置为
NULL。 - 适用场景:当子表的记录在父表记录删除后依然有意义时,外键列必须允许
NULL。 - 优点:保留了子表记录,同时删除或更新父表记录。
- 缺点:如果没有后续维护,可能导致孤立的数据。
1.3.4、NO ACTION(等价于 RESTRICT)
- 描述:禁止删除或更新父表中的记录,如果该记录在子表中有引用。
- 适用场景:强制父表记录必须首先解除子表中的关联。
- 优点:明确控制了数据的删除或更新,防止意外影响子表数据。
- 缺点:操作复杂性增加,要求开发者手动处理关联关系。
2、外键类型适用场景总结(表格)
| 外键类型 | 适用场景 | 注意事项 |
|---|---|---|
| CASCADE | 父子关系强关联,父表删除或更新后子表无条件跟随。 | 谨慎使用,避免误删除或误更新。 |
| SET NULL | 子表记录在父表删除或更新后仍有意义,允许外键列为 NULL。 | 子表的外键列必须允许 NULL,需谨防数据孤立。 |
| NO ACTION / RESTRICT | 强制要求父表记录的删除或更新必须先解除子表关联。 | 增加了操作复杂性,但能严格保护数据完整性。 |
3、外键于业务开发而言的优缺点
3.1、优点
- 数据完整性: 防止孤立记录,确保父表与子表之间的关联关系一致。
- 自动化处理: 配合 CASCADE 或 SET NULL,可以自动处理相关记录,减少手动操作的复杂性。
- 业务约束: 通过外键约束明确表间关系,增强业务逻辑的约束力。
3.2、缺点
- 性能开销: 外键约束会对插入、更新、删除操作产生额外的性能开销,尤其是在大量操作时。
- 操作复杂性: 需要对数据表操作进行规划,增加开发维护成本。
- 限制灵活性: 外键约束的存在可能限制某些业务操作,例如无法随意删除父表记录。
4、外键的使用注意事项
- 引擎限制: MySQL 的外键功能仅支持 InnoDB 存储引擎。
- 索引要求: 外键列和被引用列都必须建立索引(通常是主键或唯一键)。
- 规划数据关系: 在设计时需明确父表与子表之间的关系和操作逻辑,避免误操作。
- 性能考虑: 在高并发或大规模数据操作时,外键可能影响性能,需谨慎权衡。
结束语:业务开发时,根据需求使用或者去除掉外键,使用外键时,可以参考本篇的介绍,建立适合业务场景的外键。
——如果觉得文章有用💪,点个赞,支持一下👏!——
相关文章:
MySQL外键类型与应用场景总结:优缺点一目了然
前言: MySQL的外键简介:在 MySQL 中,外键 (Foreign Key) 用于建立和强制表之间的关联,确保数据的一致性和完整性。外键的作用主要是限制和维护引用完整性 (Referential Integrity)。 主要体现在引用操作发生变化时的处理方式&…...
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的网上书店管理系统的设计与实现
开题报告 本研究论文主要介绍了基于Spring Boot框架开发的全面网上书店管理系统的构建与实现。该系统以用户为核心,提供了丰富的个性化服务功能。首先,系统支持用户进行便捷的登录注册操作,并具备安全可靠的密码修改机制,同时允许…...
力扣面试题 - 40 迷路的机器人 C语言解法
题目: 设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。 网格中的障碍物和空…...
ElementPlus 自定义封装 el-date-picker 的快捷功能
文章目录 需求分析 需求 分析 我们看到官网上给出的案例如下,但是不太满足我们用户想要的快捷功能,因为不太多,因此需要我们自己封装一些,方法如下 外部自定义该组件的快捷内容 export const getPickerOptions () > {cons…...
二百八十二、ClickHouse——删除Linux中的ClickHouse
一、目的 由于ClickHosue的库表发生变化,需要删除原有的表结构数据,才能直接把脚本里文件重新安装 二、删除步骤 1、关闭ClickHouse服务 systemctl stop clickhouse-server 2、卸载ClickHouse软件包 sudo yum remove clickhouse-server clickhouse…...
c++ 命名空间使用规则
之前一直没搞懂为什么c 用了using namespace std;就能直接调用内部的类,直接调用内部函数 今天试着实现了一下: #include <iostream>// 命名空间 namespace mp{ class point{public: // 构造函数point(int x 0, int y 0) : x(x), y(y) {}//…...
从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性
作者:来自 Elastic Bahubali Shetti, Chris DiStasio 宣布 Elastic Cloud Serverless 上的 Elastic Observability 正式发布 — 一款完全托管的可观察性解决方案。 随着组织规模的扩大,一个能够处理分布式云环境的复杂性并提供实时洞察的可观察性解决方…...
Pandas系列|第二期:Pandas中的数据结构
1.Pandas中的数据结构:Series和DataFrame Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。 Series 是一…...
Hadoop中MapReduce过程中Shuffle过程实现自定义排序
文章目录 Hadoop中MapReduce过程中Shuffle过程实现自定义排序一、引言二、实现WritableComparable接口1、自定义Key类 三、使用Job.setSortComparatorClass方法2、设置自定义排序器3、自定义排序器类 四、使用示例五、总结 Hadoop中MapReduce过程中Shuffle过程实现自定义排序 一…...
数位dp-acwing
题目:Windy数 1083. Windy数 - AcWing题库 分析 不能有前导0,初始化的时候需要有前导0,因为除了最高位数其他位数可以。 windy : 2 5 1 类似这样的数 第二位与第一位相差3 > 2 分类讨论 : 1. 位数跟 n 同位数 的…...
智慧园区小程序开发制作功能介绍
智慧园区小程序开发制作功能介绍 智慧园区小程序系统作为一款面向园区企业的一站式线上服务平台,可为企业提供数智化的园区办公服务。智慧园区小程序功能介绍 1、园区公告、政策信息查看足不出户掌握最新动态,“园区公告、政策信息”等信息。首页点击对应…...
STM32高级 物联网之Wi-Fi通讯
Wi-Fi基础知识 Wi-Fi由来 Wi-Fi,又称“无线网路”,是Wi-Fi联盟的商标,一个基于IEEE 802.11标准的无线局域网技术。“Wi-Fi”常写作“WiFi”或“Wifi”,但是这些写法并没有被Wi-Fi联盟认可。 Wi-Fi这个术语经常被误以为是指无线保真(Wireless Fidelity),类似历史悠久的…...
LLM预训练recipe — 摘要版
文章核心主题: 本文深入探讨了从零开始进行大型语言模型(LLM)预训练(pretrain)的各个环节,侧重方法论和实践细节,旨在普及预训练过程中的关键步骤、常见问题及避坑技巧,而非技术原理…...
波动理论、传输线和S参数网络
波动理论、传输线和S参数网络 传输线 求解传输线方程 对于传输线模型,我们通常用 R L G C RLGC RLGC 来表示: 其中 R R R 可以表示导体损耗,由于电子流经非理想导体而产生的能量损耗。 G G G 表示介质损耗,由于非理想电介质…...
nginx-1.23.2版本RPM包发布
nginx-1.23.2-0.x86_64.rpm用于CentOS7系统的安装,安装路径与编译安装是同一个路径。安装方法: 将nginx-1.23.2-0.x86_64.rpm上传至目标服务器,执行rpm -ivh nginx-1.23.2-0.x86_64.rpm命令进行安装。 卸载方法: 卸载前先将nginx服…...
如何用WPS AI提高工作效率
对于每位职场人而言,与Word、Excel和PPT打交道几乎成为日常工作中不可或缺的一部分。在办公软件的选择上,国外以Office为代表,而在国内,WPS则是不可忽视的一大选择。当年一代天才程序员求伯君创造了WPS,后面雷军把它装…...
LabVIEW应用在工业车间
LabVIEW作为一种图形化编程语言,以其强大的数据采集和硬件集成功能广泛应用于工业自动化领域。在工业车间中,LabVIEW不仅能够实现快速开发,还能通过灵活的硬件接口和直观的用户界面提升生产效率和设备管理水平。尽管其高成本和初期学习门槛可…...
Elasticsearch:normalizer
一、概述 Elastic normalizer是Elasticsearch中用于处理keyword类型字段的一种工具,主要用于对字段进行规范化处理,确保在索引和查询时保持一致性。 Normalizer与analyzer类似,都是对字段进行处理,但normalizer不会对字段进…...
动态规划子序列问题系列一>等差序列划分II
题目: 解析: 1.状态表示: 2.状态转移方程: 这里注意有个优化 3.初始化: 4.填表顺序: 5.返回值: 返回dp表总和 代码: public int numberOfArithmeticSlices(int[] nums) {in…...
48页PPT|2024智慧仓储解决方案解读
本文概述了智慧物流仓储建设方案的行业洞察、业务蓝图及建设方案。首先,从政策层面分析了2012年至2020年间国家发布的促进仓储业、物流业转型升级的政策,这些政策强调了自动化、标准化、信息化水平的提升,以及智能化立体仓库的建设࿰…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
