MySQL之外键约束和表关系

 前言

一个项目中如果将所有的数据都存放在一张表中是不合理的,比如一个员工信息,公司只有2个部门,但是员工有1亿人,就意味着员工信息这张表中的部门字段的值需要重复存储,极大的浪费资源,因此可以定义一个部门表和员工信息表进行关联,而关联的方式就是外键。

外键(Foreign Key)

按照上述所说,一张表存储员工信息会极大的浪费资源,重复数据太多,这个问题就类似于将所有的代码都写在了一个py文件中,因此我们可以将一个表拆成不同的表,在这不同的表之间建立关联,而建立关联就需要使用外键foreign key。外键也属于约束条件的一种。

如何确定表关系

表与表之间的关系有三种一对多、多对多、一对一。那么如何确定表与表之间的关系呢?

在确定表与表之间的关系时建议换位思考,什么意思呢?就是分别站在两张表的角度去考虑,比如员工表和部门表的关系:

先站在员工表的角度:员工表中一个员工能否属于多个部门呢?答案是不能

再站在部门表的角度:部门表中一个部门能否有多个员工呢?答案是可以

因此员工表与部门表是单向的一对多,那么员工表和部门表就是一对多的关系。

如何建立表关系

在建立表关系时,表与表之间的关联通常以主键id作为关联字段。

一对多关系 - 员工表和部门表

在MySQL的关系在没有多对一的概念,一对多和多对一都是一对多。在创建一对多表关系时需要遵循以下几点:

第一,外键字段建立在多的一方,即员工表

第二,在创建表的时候,一定要先创建被关联一方,即部门表

第三,在录入数据的时候也必须先录入被关联表的数据,即部门表的数据

第四,当不同的表建立关系时,需要进行级联更新和删除也可以称为同步更新同步删除,如果不建立级联更新和删除的话,无法对被关联表中被关联的数据进行删除或者修改id的操作,因为两张表是相互关联的。

-- 创建被关联表,部门表
mysql> create table bm(
    id int primary key auto_increment, 
    bm_name varchar(10), 
    bm_desc char(64)
);
Query OK, 0 rows affected (0.01 sec)

mysql> desc bm;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| bm_name | varchar(10) | YES  |     | NULL    |                |
| bm_desc | char(64)    | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

-- 创建外键所在的表,员工表
mysql> create table yg(
    id int primary key auto_increment, 
    yg_name varchar(6), 
    bm_id int, 
    foreign key(bm_id) references bm(id)  -- 表示bm_id是外键字段,关联到bm表中的id字段
    on update cascade  # 级联更新
    on delete cascade  # 级联删除
);
Query OK, 0 rows affected (0.10 sec)

mysql> desc yg;
+---------+------------+------+-----+---------+----------------+
| Field   | Type       | Null | Key | Default | Extra          |
+---------+------------+------+-----+---------+----------------+
| id      | int(11)    | NO   | PRI | NULL    | auto_increment |
| yg_name | varchar(6) | YES  |     | NULL    |                |
| bm_id   | int(11)    | YES  | MUL | NULL    |                |
+---------+------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)


-- 插入数据
mysql> insert into bm (bm_name, bm_desc) values ('python', '人生苦短'),('go', 'let us go');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from bm;
+----+---------+--------------+
| id | bm_name | bm_desc      |
+----+---------+--------------+
|  1 | python  | 人生苦短     |
|  2 | go      | let us go    |
+----+---------+--------------+
2 rows in set (0.00 sec)


mysql> insert into yg (yg_name, bm_id) values ('xu', 1), ('zhuang', 2), ('lili', 1);
Query OK, 3 rows affected (0.09 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from yg;
+----+---------+-------+
| id | yg_name | bm_id |
+----+---------+-------+
|  2 | xu      |     1 |
|  3 | zhuang  |     2 |
|  4 | lili    |     1 |
+----+---------+-------+
3 rows in set (0.00 sec)

-- 外键关联的数据必须在被关联表中存在否则会报错哦~
mysql> insert into yg (yg_name, bm_id) values ('xu', 3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

-- 如果不使用级联更新和删除的话会出现下面的错误,下述的SQL语句后面的文章都会介绍。。。
mysql> update bm set id=5 where id=2;  -- 将bm表中id=2的记录改为id=5
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

mysql> delete from bm where id =2;  -- 删除bm表中id为2的那条记录
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`)) 

多对多

多对多的关系以书籍和作者为例进行详细介绍,为什么书籍和作者属于多对多的关系呢?

先站在书籍表的角度:一本书是否可以有多个作者?答案是可以

再站在作者表的角度:一个作者是否可以写多本书?答案是可以

书籍表和作者表是双向的一对多那么这两张表的关系就是多对多。

我们先来创建两张表:

-- 创建书籍表
create table book(
    id int primary key auto_increment,
    title varchar(32),
    price int,
    author_id int,
    foreign key(author_id) references author(id)
    on update cascade
    on delete cascade
);

-- 创建作者表
create table author(
    id int primary key auto_increment,
    name varchar(32),
    age int,
    book_id int,
    foreign key(book_id) references book(id)
    on update cascade
    on delete cascade
);

如果按照上述方式创建表的话肯定是不可能成功的,在创建一对多的表关系时我我们说要先创建被关联表,也就是没有外键的表,可是多对多关系是双向的一对多,每张表中都会有外键的存在,怎么办呢?解决方案就是创建第三张表,这第三张表用来专门存储多对多关系的两张表的关联。

-- 创建书籍表
mysql> create table book(
    id int primary key auto_increment, 
    name varchar(10), 
    price int
);
Query OK, 0 rows affected (0.01 sec)

-- 创建作者表
mysql> create table author(
    id int primary key auto_increment, 
    name varchar(6), 
    age int
);
Query OK, 0 rows affected (0.01 sec)


-- 创建第三章表,存储book和author表的关联关系
mysql> create table book2author(
    id int primary key auto_increment, 
    author_id int, 
    book_id int, 
    foreign key(author_id) references author(id) 
    on update cascade 
    on delete cascade, 	
    foreign key(book_id) references book(id) 
    on update cascade 
    on delete cascade);
Query OK, 0 rows affected (0.02 sec)

一对一

如果一张表的字段特别多,每次查询数据时又不是所有的字段都能用的到,我们就可以将表一一分为二,比如说用户信息表,用户的信息包括用户名 密码 用户的年龄 用户的性别 地址 电话等等,可能经常用的只有用户的用户名和密码,这种情况我们就可以将一张用户信息表拆分成用户基本信息表和用户详细信息表,同样判断这两张表的关系还是通过换位思考:

首先看用户基本信息表:一个用户能否有多个详细信息?答案是不可以;

再看用户详情表:一个用户详情能否属于多个用户?答案是不可以;

单向的一对多都不成立,那么两者之间的表关系就是一对一或者没有关系。

使用SQL语句建立一对一的外键关系时,外键建在任意一方都可以,但是推荐将外键建在查询频率较高的表中,同样的,在创建表时还是先创建被关联表。

-- 创建用户详情表
create table authordetail(
	id int primary key auto_increment,
	phone int,
	addr varchar(64)
);

-- 用户基本信息表
create table author(
	id int primary key auto_increment,
    name varchar(32),
    age int,
    authordetali_id int,
    foreign key(authordetali_id) references authordetali(id)
    on update cascade
    on delete cascade
);

表关系总结

表关系建立需要使用外键foreign key,判断表与表之间的关系通过换位思考的方式。

一对多表关系:外键建在多的一方

一对一表关系:外键建在任意一方都可以,推荐建在查询频率高的一方

多对多表关系:需要单独创建第三张表存储两张表的关联关系

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

突破性概念“整车智能”背后,比亚迪又在蓄力何方?

比亚迪再以“整车智能”的颠覆性创意惊艳我们,他们这次又在酝酿哪些革命性技术,引领行业? 2024年的比亚迪梦想日,为汽车行业带来了一次全新的飞跃。这家传统但很有实力,却又颇有野心的自主品牌车企,再次以开…

使用Python在本地生成助记词

新建并打开一个空文件夹 逐行 执行命令 python3 -m pip install --upgrade pippip3 install eth_accountpip3 install web3touch acco.py然后看到文件夹下面会有个acco.py文件 将把下面的代码粘贴到acco.py中保存。 import os from eth_account import Accountif __name__ …

AI视频智能识别技术在智慧农业大棚升级改造管理场景中的应用方案

一、需求分析 随着科技的进步和农业现代化的推进,智能化技术逐渐成为现代农业发展的重要支撑。农业大棚作为现代农业的重要组成部分,其智能化改造对于提高农业生产效率、降低成本、增加收益具有重要意义。利用先进的信息化手段来对农业大棚进行管理&…

防伪技术行业研究:年复合增长率约为10%

近年来,我国各种新的防伪技术不断涌现,部分防伪技术已经达到国际先进水平,并广泛应用于产品防伪、票证防伪等领域,推动了防伪行业的持续、健康发展。 常见的产品防伪技术有:隐形分子技术、二维码防伪、揭开留底防伪、安…

【C语言】- 设置控制台标题、编码、文字颜色、大小和字体

【C语言】- 设置控制台标题、编码、文字颜色、大小和字体 文章目录 【C语言】- 设置控制台标题、编码、文字颜色、大小和字体1 - 设置控制台标题2 - 设置控制台编码3 - 设置控制台字体和大小参考链接 1 - 设置控制台标题 因为要用到 Windows API,所以需要包含头文件…

systemverilog/verilog文件操作

1、Verilog文件操作 Verilog具有系统任务和功能,可以打开文件、将值输出到文件、从文件中读取值并加载到其他变量和关闭文件。 1.1 、Verilog文件操作 1.1.1、打开和关闭文件 module tb; // 声明一个变量存储 file handler integer fd; initial begin // 以写权限打开一个文…

计算机vcruntime140.dll丢失要怎么解决,快速解决dll报错问题

在计算机系统中,vcruntime140.dll是一个至关重要的动态链接库文件(DLL),它是Visual C Redistributable运行时组件的重要组成部分。这个特定的.dll文件承载了大量的运行时函数和资源,对于许多基于Windows的应用程序来说…

基于动态顺序表实现通讯录项目

本文中,我们将使用顺序表的结构来完成通讯录的实现。 我们都知道,顺序表实际上就是一个数组。而使用顺序表来实现通讯录,其内核是将顺序表中存放的数据类型改为结构体,将联系人的信息存放到结构体中,通过对顺序表的操…

【微服务核心】ZooKeeper

文章目录 1. 简介2. 下载与安装2.1 单机版2.2 集群版 3. 选举机制3.1 首次启动3.2 非首次启动 4. 客户端常用命令行操作4.1 查看节点信息4.2 节点类型4.3 监听器原理4.4 写数据流程 5. 编程实现监听服务动态上下线6. 分布式锁6.1 手写简易分布式锁6.2 Curator 框架 7. 进阶知识…

python对象方法 反射

前言 类实例化得到的对象可以直接调用类中定义的函数,并且可以将对象本身作为第一个参数,那么类能不能也能像对象一样使用类体中的函数而不需要传递第一个参数呢?如果我们使用别人封装好的类,如何判断这个类或者对象是否有某个属…

未来 AI 可能给哪些产业带来哪些进步与帮助?

AI时代如何要让公司在创新领域领先吗?拥抱这5种创新技能,可以帮助你的公司应对不断变化。包括人工智能、云平台应用、数据分析、 网络安全和体验设计。这些技能可以帮助你提高业务效率、保护公司知识资产、明智决策、满足客户需求并提高销售额。 现在就加…

Python入门到精通(三)——Python循环语句

Python循环语句 一、while 循环 1、基础语法 2、嵌套应用 二、for 循环 1、基础语法 2、嵌套应用 三、循环中断:break 和 continue 1、break 2、continue 四、综合案例 一、while 循环 1、基础语法 while的条件需得到布尔类型,True表示继续循环…

一款真正可用的支付系统,可搭建自己的易支付系统,开源无后门

应用介绍 介绍: thinkphp开发的风吹雪支付系统易支付去后台验证版本,支持代理系统,适合搭建易支付系统,完整100%可运行网站源码。是为数不多的一款真正可用的支付系统,开源无后门可运营。 自带微信支付宝官方通道,资质…

探秘网络爬虫的基本原理与实例应用

1. 基本原理 网络爬虫是一种用于自动化获取互联网信息的程序,其基本原理包括URL获取、HTTP请求、HTML解析、数据提取和数据存储等步骤。 URL获取: 确定需要访问的目标网页,通过人工指定、站点地图或之前的抓取结果获取URL。 HTTP请求&#…

一键拆分,轻松整理,高效管理文本文件,让工作更轻松!

在日常工作中,我们经常需要处理大量的文本文件。如何快速整理这些文件,方便管理和使用成为了关键问题。为此,我们为您推荐一款强大的一键拆分和整理工具,助您高效管理文本文件! 首先,在首助编辑高手的主页面…

Gradle——基础

1、Gradle基础 1.1、Ant/Maven/Gradle对比 无论那种项目构建工具,都有自身的优势和劣势,所以选择一款最适合项目的就是最好的! 1.2、Gradle项目目录结构 Gradle项目默认目录结构和Maven项目的目录结构一致,都是基于约定大于配置…

好物周刊#37:元气桌面

https://github.com/cunyu1943/JavaPark https://yuque.com/cunyu1943 村雨遥的好物周刊,记录每周看到的有价值的信息,主要针对计算机领域,每周五发布。 一、项目 1. MallChat 一个既能购物又能聊天的电商系统。以互联网企业级开发规范的…

《斗罗大陆Ⅱ绝世唐门》美女盘点:高颜值角色吸睛无数,玄机科技再塑国漫辉煌

在国漫崛起的大潮中,玄机科技以其精湛的建模技术和独特的审美视角,打造了一部又一部备受瞩目的佳作。其中,《绝世唐门》作为玄幻类动画的代表,凭借其丰富的人物设定和颜值爆表的角色,赢得了无数观众的喜爱和追捧。今天…

DC-3靶机刷题记录

靶机下载地址: 链接:https://pan.baidu.com/s/1-P5ezyt5hUbmmGMP4EI7kw?pwdrt2c 提取码:rt2c 参考: http://t.csdnimg.cn/hhPi8https://www.vulnhub.com/entry/dc-32,312/ 官网http://t.csdnimg.cn/5mVZ7DC-3 (1).pdfhttps://…

裸辞后找工作有多难?分享个人经历+面经+学习路线【内含免费下载初级前端面试题】- 回忆我的2023

👉 个人博客主页 👈 📝 一个努力学习的程序猿 专栏: HTML和CSS JavaScript jQuery Vue Vue3 React TypeScript uni-app Linux 前端面试分享 前端学习方案分享(VitePress、html2canvasjspdf、vuedraggable、videojs) 前端踩坑日记&…