当前位置: 首页 > news >正文

MySQL外键类型与应用场景总结:优缺点一目了然

前言

MySQL的外键简介:在 MySQL 中,外键 (Foreign Key) 用于建立和强制表之间的关联,确保数据的一致性和完整性。外键的作用主要是限制和维护引用完整性 (Referential Integrity)。

  • 主要体现在引用操作发生变化时的处理方式(即 ON DELETEON UPDATE 的行为)。
  • 外键类型一共有四种RESTRICTCASCADESET NULLNO 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 = 2user_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 = 1user_id的值变为NULLorder_id = 2user_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;就能直接调用内部的类&#xff0c;直接调用内部函数 今天试着实现了一下&#xff1a; #include <iostream>// 命名空间 namespace mp{ class point{public: // 构造函数point(int x 0, int y 0) : x(x), y(y) {}//…...

从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性

作者&#xff1a;来自 Elastic Bahubali Shetti, Chris DiStasio 宣布 Elastic Cloud Serverless 上的 Elastic Observability 正式发布 — 一款完全托管的可观察性解决方案。 随着组织规模的扩大&#xff0c;一个能够处理分布式云环境的复杂性并提供实时洞察的可观察性解决方…...

Pandas系列|第二期:Pandas中的数据结构

1.Pandas中的数据结构&#xff1a;Series和DataFrame Pandas 的主要数据结构是 Series &#xff08;一维数据&#xff09;与 DataFrame&#xff08;二维数据&#xff09;&#xff0c;这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。 Series 是一…...

Hadoop中MapReduce过程中Shuffle过程实现自定义排序

文章目录 Hadoop中MapReduce过程中Shuffle过程实现自定义排序一、引言二、实现WritableComparable接口1、自定义Key类 三、使用Job.setSortComparatorClass方法2、设置自定义排序器3、自定义排序器类 四、使用示例五、总结 Hadoop中MapReduce过程中Shuffle过程实现自定义排序 一…...

数位dp-acwing

题目&#xff1a;Windy数 1083. Windy数 - AcWing题库 分析 不能有前导0&#xff0c;初始化的时候需要有前导0&#xff0c;因为除了最高位数其他位数可以。 windy &#xff1a; 2 5 1 类似这样的数 第二位与第一位相差3 > 2 分类讨论 &#xff1a; 1. 位数跟 n 同位数 的…...

智慧园区小程序开发制作功能介绍

智慧园区小程序开发制作功能介绍 智慧园区小程序系统作为一款面向园区企业的一站式线上服务平台&#xff0c;可为企业提供数智化的园区办公服务。智慧园区小程序功能介绍 1、园区公告、政策信息查看足不出户掌握最新动态&#xff0c;“园区公告、政策信息”等信息。首页点击对应…...

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 — 摘要版

文章核心主题&#xff1a; 本文深入探讨了从零开始进行大型语言模型&#xff08;LLM&#xff09;预训练&#xff08;pretrain&#xff09;的各个环节&#xff0c;侧重方法论和实践细节&#xff0c;旨在普及预训练过程中的关键步骤、常见问题及避坑技巧&#xff0c;而非技术原理…...

波动理论、传输线和S参数网络

波动理论、传输线和S参数网络 传输线 求解传输线方程 对于传输线模型&#xff0c;我们通常用 R L G C RLGC RLGC 来表示&#xff1a; 其中 R R R 可以表示导体损耗&#xff0c;由于电子流经非理想导体而产生的能量损耗。 G G G 表示介质损耗&#xff0c;由于非理想电介质…...

nginx-1.23.2版本RPM包发布

nginx-1.23.2-0.x86_64.rpm用于CentOS7系统的安装&#xff0c;安装路径与编译安装是同一个路径。安装方法&#xff1a; 将nginx-1.23.2-0.x86_64.rpm上传至目标服务器&#xff0c;执行rpm -ivh nginx-1.23.2-0.x86_64.rpm命令进行安装。 卸载方法&#xff1a; 卸载前先将nginx服…...

如何用WPS AI提高工作效率

对于每位职场人而言&#xff0c;与Word、Excel和PPT打交道几乎成为日常工作中不可或缺的一部分。在办公软件的选择上&#xff0c;国外以Office为代表&#xff0c;而在国内&#xff0c;WPS则是不可忽视的一大选择。当年一代天才程序员求伯君创造了WPS&#xff0c;后面雷军把它装…...

LabVIEW应用在工业车间

LabVIEW作为一种图形化编程语言&#xff0c;以其强大的数据采集和硬件集成功能广泛应用于工业自动化领域。在工业车间中&#xff0c;LabVIEW不仅能够实现快速开发&#xff0c;还能通过灵活的硬件接口和直观的用户界面提升生产效率和设备管理水平。尽管其高成本和初期学习门槛可…...

Elasticsearch:normalizer

一、概述 ‌Elastic normalizer‌是Elasticsearch中用于处理keyword类型字段的一种工具&#xff0c;主要用于对字段进行规范化处理&#xff0c;确保在索引和查询时保持一致性。 Normalizer与analyzer类似&#xff0c;都是对字段进行处理&#xff0c;但normalizer不会对字段进…...

动态规划子序列问题系列一>等差序列划分II

题目&#xff1a; 解析&#xff1a; 1.状态表示&#xff1a; 2.状态转移方程&#xff1a; 这里注意有个优化 3.初始化&#xff1a; 4.填表顺序&#xff1a; 5.返回值&#xff1a; 返回dp表总和 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {in…...

48页PPT|2024智慧仓储解决方案解读

本文概述了智慧物流仓储建设方案的行业洞察、业务蓝图及建设方案。首先&#xff0c;从政策层面分析了2012年至2020年间国家发布的促进仓储业、物流业转型升级的政策&#xff0c;这些政策强调了自动化、标准化、信息化水平的提升&#xff0c;以及智能化立体仓库的建设&#xff0…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...