【重学 MySQL】六十六、外键约束的使用

news2024/10/23 1:37:56

【重学 MySQL】六十六、外键约束的使用

  • 外键约束的概念
  • 关键字
  • 主表和从表/父表和子表
  • 外键约束的创建条件
  • 外键约束的特点
  • 外键约束的创建方式
  • 外键约束的删除
  • 外键约束的约束等级
  • 外键约束的级联操作
  • 外键约束的示例
  • 外键约束的作用
  • 开发场景
  • 阿里开发规范

在这里插入图片描述
在MySQL中,外键约束是一种重要的数据库约束,用于确保表中的数据完整性。它强制子表中的每个记录都引用主表中的一个现有的记录,从而维护数据的一致性和完整性。

外键约束的概念

外键约束是作用于表中字段上的规则,用于限制存储在表中的数据。它使得两张表的数据之间能够建立连接,从而确保数据的一致性和完整性。

关键字

FOREIGN KEY

主表和从表/父表和子表

主表(父表):被引用的表,被参考的表

从表(子表):引用别人的表,参考别人的表

例如:员工表的员工所在部门这个字段的值要参考部门表:部门表是主表,员工表是从表。

例如:学生表、课程表、选课表:选课表的学生和课程要分别参考学生表和课程表,学生表和课程表是主表,选课表是从表。

外键约束的创建条件

  1. 主表存在:主表必须已经存在于数据库中,或者是当前正在创建的表。
  2. 主键定义:必须为主表定义主键。
  3. 主键非空:主键不能包含空值,但允许在外键中出现空值。
  4. 列匹配:在主表的表名后面指定列名或列名的组合,这个列或列的组合必须是主表的主键。同时,外键中列的数目必须和主表的主键中列的数目相同。
  5. 数据类型一致:外键中列的数据类型必须和主表主键列的数据类型相同。

外键约束的特点

  1. 从表的外键列,必须引用/参考主表的主键或唯一约束的列
    为什么?因为被依赖/被参考的值必须是唯一的

  2. 在创建外键约束时,如果不给外键约束命名,默认名不是列名,而是自动产生一个外键名(例如 student_ibfk_1;),也可以指定外键约束名。

  3. 创建(CREATE)表时就指定外键约束的话,先创建主表,再创建从表

  4. 删表时,先删从表(或先删除外键约束),再删除主表

  5. 当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据

  6. 在“从表”中指定外键约束,并且一个表可以建立多个外键约束

  7. 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一样,创建子表时,就会出现错误“ERROR 1005 (HY000): Can’t create table.database.tablename’(errno: 150)”。
    例如:都是表示部门编号,都是int类型。

  8. 当创建外键约束时,系统默认会在所在的列上建立对应的普通索引。但是索引名是外键的约束名。(根据外键查询效率很高)

  9. 删除外键约束后,必须手动删除对应的索引

外键约束的创建方式

  1. 在创建表时设置外键约束
CREATE TABLE child_table (
    child_column INT NOT NULL,
    PRIMARY KEY (child_column),
    FOREIGN KEY (child_column) REFERENCES parent_table (parent_column)
);

在上述语法中,child_table是子表名称,parent_table是主表名称,child_column是子表中的外键列,parent_column是主表中的引用列。

  1. 通过ALTER TABLE添加外键约束

如果表已经存在,并且需要添加外键约束,可以使用ALTER TABLE语句。例如:

ALTER TABLE child_table
ADD CONSTRAINT fk_name
FOREIGN KEY (child_column)
REFERENCES parent_table (parent_column);

其中,fk_name是外键约束的名称,child_column是子表中的外键列,parent_table是主表名称,parent_column是主表中的引用列。

外键约束的删除

如果不再需要外键约束,可以使用ALTER TABLE语句将其删除。例如:

ALTER TABLE child_table
DROP FOREIGN KEY fk_name;

其中,child_table是子表名称,fk_name是要删除的外键约束的名称。

外键约束的约束等级

在MySQL中,外键约束的约束等级决定了当主表中的记录被更新或删除时,子表中相应的外键记录将如何响应。

  1. CASCADE

    • 含义:当主表中的记录被删除或更新时,子表中所有引用该记录的外键记录也会被相应地删除或更新。
    • 示例:如果主表中的某个部门被删除,那么所有属于该部门的员工记录(在子表中)也会被自动删除。
  2. SET NULL

    • 含义:当主表中的记录被删除或更新时,子表中所有引用该记录的外键记录的外键字段会被设置为NULL。这要求子表的外键列不能为NOT NULL约束。
    • 示例:如果主表中的某个部门被删除,那么所有属于该部门的员工记录(在子表中)的部门ID字段会被设置为NULL。
  3. NO ACTIONRESTRICT

    • 含义:这两种约束等级在MySQL中的行为是相似的。它们都会阻止对主表中被引用的记录进行删除或更新操作,如果子表中存在引用该记录的外键记录。
    • 示例:如果尝试删除主表中某个被子表引用的部门记录,数据库将拒绝该删除操作,直到所有引用该部门的员工记录被删除或更新。
  4. SET DEFAULT

    • 含义:这个约束等级在MySQL的InnoDB存储引擎中是不被支持的。理论上,它意味着当主表中的记录被删除或更新时,子表中所有引用该记录的外键记录会被设置为一个默认值。
    • 注意:由于InnoDB不支持,因此在实际应用中不会使用此约束等级。

在实际应用中,选择哪种约束等级取决于具体的业务需求。例如,如果希望当主表中的记录被删除时,子表中相应的记录也被删除,那么可以选择CASCADE约束等级。如果希望保留子表中的记录,但将外键字段设置为NULL以表示不再引用主表中的记录,那么可以选择SET NULL约束等级。

需要注意的是,外键约束的创建和使用需要满足一定的条件,如主表必须存在、主键必须定义、数据类型必须一致等。此外,不同的数据库管理系统(DBMS)可能对外键约束的支持和实现方式有所不同,因此在使用时需要参考具体DBMS的文档和指南。

外键约束的级联操作

  1. 级联删除:当主表中的记录被删除时,如果子表中有依赖于该记录的外键,则这些外键对应的记录也将被自动删除。这可以通过在创建外键约束时指定ON DELETE CASCADE选项来实现。
  2. 级联更新:当主表中的记录被更新时,如果子表中有依赖于该记录的外键,并且希望这些外键对应的记录也相应更新,则可以使用ON UPDATE CASCADE选项。

外键约束的示例

假设有两个表:department(部门表)和employee(员工表)。我们希望确保每个员工都属于一个存在的部门,因此可以在employee表中为dept_id列添加外键约束,引用department表中的id列。

-- 创建部门表
CREATE TABLE department (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    PRIMARY KEY (id)
);

-- 创建员工表并添加外键约束
CREATE TABLE employee (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    job VARCHAR(20),
    salary INT,
    dept_id INT,
    PRIMARY KEY (id),
    FOREIGN KEY (dept_id) REFERENCES department(id)
);

或者,如果员工表已经存在,可以使用ALTER TABLE语句添加外键约束:

ALTER TABLE employee
ADD CONSTRAINT fk_employee_department
FOREIGN KEY (dept_id)
REFERENCES department(id);

这样,当尝试在employee表中插入一个不存在的dept_id时,数据库将拒绝该操作,从而保证了数据的一致性和完整性。

外键约束的作用

  1. 保证数据完整性:外键约束可防止在子表中插入指向不存在记录的外键值。
  2. 强制数据关联:外键约束强制子表中的记录与主表中的记录相关联。
  3. 简化数据维护:外键约束简化了数据的维护,因为当主表中的记录被删除或更新时,子表中的记录将自动更新或删除(如果启用了级联操作)。

综上所述,外键约束在MySQL中扮演着重要的角色,它有助于维护数据库中的数据完整性和一致性。在使用外键约束时,需要确保满足其创建条件,并正确地创建和删除外键约束。

开发场景

问题1:如果两个表之间有关系(一对一、一对多),比如:员工表和部门表(一对多),它们之间是否一定要建外键约束?

答:不是的

问题2:建和不建外键约束有什么区别?

答:建外键约束,你的操作(创建表、删除表、添加、修改、删除)会受到限制,从语法层面受到限制。例如:在员工表中不可能添加一个员工信息,它的部门的值在部门表中找不到。

不建外键约束,你的操作(创建表、删除表、添加、修改、删除)不受限制,要保证数据的引用完整性,只能依靠程序员的自觉,或者是在Java程序中进行限定。例如:在员工表中,可以添加一个员工的信息,它的部门指定为一个完全不存在的部门。

问题3:那么建和不建外键约束和查询有没有关系?

答:没有

在 MySQL 里,外键约束是有成本的,需要消耗系统资源。对于大并发的 SQL 操作,有可能会不适合。比如大型网站的中央数据库,可能会因为外键约束的系统开销而变得非常慢。所以, MySQL 允许你不使用系统自带的外键约束,在应用层面完成检查数据一致性的逻辑。也就是说,即使你不用外键约束,也要想办法通过应用层面的附加逻辑,来实现外键约束的功能,确保数据的一致性。

阿里开发规范

强制】不得使用外键与级联,一切外键概念必须在应用层解决。

说明:(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2221214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

免费开源的微信开发框架

近年来,随着人工智能技术的快速发展,聊天机器人在各个领域得到了广泛的应用。在社交媒体中,自动回复成为了一个流行的功能,让用户可以方便地与机器人进行互动。gewe框架,一个开源的微信聊天机器人框架,实现…

Android 10.0 Camera2 拍照镜像功能实现

1.前言 在10.0的系统rom定制化开发中,在进行camera2的相关拍照功能开发中,在某些时候会遇到拍照照片 左右镜像的问题,就是照片左半边和右半边是反的,所以就需要在拍照的时候保存图片的时候实现 左右镜像功能,接下来就来分析下拍照保存图片的流程 2.Camera2 拍照镜像功能实…

银行数字化转型导师坚鹏:2025年银行开门红8大思考

2025年银行开门红8大思考:与2024年相比有哪些新的变化与不同? 1. ‌员工:从认清现实到重塑信心‌ 经济下行周期开启,叠加外部不稳定、不确定因素增加,让很多员工不适应、不习惯,甚至产生躺平心态。2025年…

信息学奥赛复赛复习18-CSP-J2022-01解密-二分答案、二分找边界、二分时间复杂度、二分求最小

PDF文档回复:20241017 1 P8814 [CSP-J 2022] 解密 [题目描述] 给定一个正整数 k,有 k 次询问,每次给定三个正整数 ni,ei,di,求两个正整数 pi,qi,使 nipiqi、eidi(pi−1)(qi−1)1 [输入格式] 第一行一个正整数 k,表…

leetcode动态规划(十)-0-1背包理论基础(一维数组)

一维dp数组(滚动数组) leetcode中无纯0-1背包问题,可从卡码网上查看题目46.0-1背包问题 一维数组来源于二维数组,其本质是对一维数组进行压缩了,压缩后需要注意在进行背包容量循环的时候采用后序遍历,而不…

Linux系统基础-进程间通信(3)_模拟实现匿名管道

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(3)_模拟实现匿名和命名管道 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论&a…

强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断

强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断 目录 强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 EEMD-MPE-KPCA-LSTM(集合经验模态分解-多尺…

无人机电机损耗!

一、电机损耗类型 机械损耗: 主要由于电机的旋转部件(如转子、轴承等)在运转过程中产生的摩擦和磨损。 长时间运行或不当维护可能加剧这种损耗。 电气损耗: 包括电阻损耗、铁芯损耗和杂散损耗等。 这些损耗主要由电流通过电…

Golang | Leetcode Golang题解之第491题非递减子序列

题目: 题解: var (temp []intans [][]int )func findSubsequences(nums []int) [][]int {ans [][]int{}dfs(0, math.MinInt32, nums)return ans }func dfs(cur, last int, nums []int) {if cur len(nums) {if len(temp) > 2 {t : make([]int, len(…

未来AI的学习能力会达到怎样的水平?

​ 大家好,我是Shelly,一个专注于输出AI工具和科技前沿内容的AI应用教练,体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具,拥抱AI时代的到来。 AI工具集1:大厂AI工具【共2…

Leetcode—192. 统计词频【中等】(Shell)

2024每日刷题(188) Leetcode—192. 统计词频 实现代码 # Read from the file words.txt and output the word frequency list to stdout. cat words.txt | tr -s \n | sort | uniq -c | sort -nr | awk {print $2, $1}运行结果 之后我会持续更新&…

学习threejs,通过THREE.Raycaster给模型绑定点击事件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Raycaster光线投射概…

DirectX11:Position Based Fluid

前言 这是我本科毕业设计项目,使用DirectX11实现一个基于PBD的流体模拟仿真,同时也算是补了Games101的大作业了。 阅读本文假设你对以下内容比较熟悉: 流体模拟:Smoothed Particle Hydrodynamics 流体模拟:Neighbor…

UNIX网络编程-传输层

概述 传输层主要包括:TCP、UDP、SCTP(流控制传输协议)! 绝大多数客户端/服务器网络应用都使用TCP/UDP。SCTP是一个较新的协议,最初设计用于跨因特网传输电话信令。 这些传输协议都转而使用网络协议IP:或是…

windows中命令行批处理脚本学习

目录 一 基础知识二 常见命令1. 输出 echo2. 注释 rem .... %...% :: goto if (10) ()3. 变量 set4. 获取参数 %数字 %*5. 退出 exit6. 复制 copy7.读取输出文件内容 type8. 帮助 命令xxx /?9.等待当前命令运行结束后,才执行下一条命令 call10. 修改字体编码 chcp11. 特殊变量…

集合框架16:HashMap的使用

视频链接:13.35 HashMap使用(1)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?spm_id_from333.788.videopod.episodes&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p35 1.创建Student类,添加无参构造…

UML之用例图详解

~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 零、什么是用例图 用例图(Use Case Diagram)是UML中一种重要的图表类型,它主要用于描述系统的功能性需求&am…

Java使用HttpClient5实现发送HTTP请求

Java 实现发送 HTTP 请求,系列文章: 《Java使用原生HttpURLConnection实现发送HTTP请求》 《Java使用HttpClient5实现发送HTTP请求》 《SpringBoot使用RestTemplate实现发送HTTP请求》 1、HttpClient5 的介绍 HttpClient5 是 Apache HttpComponents 项目…

文件处理新纪元:微信小程序的‘快递员’与‘整理师’

嗨,我是中二青年阿佑,今天阿佑将带领大家如何通过巧妙的文件处理功能,让用户体验从‘杂乱无章’到‘井井有条’的转变! 文章目录 微信小程序的文件处理文件上传:小程序的“快递服务”文件下载:小程序的“超…