MySQL 外键约束和表关系相关总结


Posted in MySQL onJune 20, 2021
目录
  • 外键(Foreign Key)
  • 如何确定表关系
  • 如何建立表关系
    • 一对多关系 - 员工表和部门表
    • 多对多
    • 一对一
  • 表关系总结

 

外键(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,判断表与表之间的关系通过换位思考的方式。

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

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

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

以上就是MySQL 外键约束和表关系相关总结的详细内容,更多关于MySQL 外键约束和表关系的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
浅谈mysql执行过程以及顺序
May 12 MySQL
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
Jun 26 MySQL
MySQL千万级数据表的优化实战记录
Aug 04 MySQL
一篇文章看懂MySQL主从复制与读写分离
Nov 07 MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
mysql中DCL常用的用户和权限控制
Mar 31 MySQL
Nebula Graph解决风控业务实践
Mar 31 MySQL
MySQL数据库事务的四大特性
Apr 20 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
MySQL数据库查询之多表查询总结
Aug 05 MySQL
MySQL常用慢查询分析工具详解
Aug 14 MySQL
MySQL 使用索引扫描进行排序
Jun 20 #MySQL
新手入门Mysql--概念
mysql获取指定时间段中所有日期或月份的语句(不设存储过程,不加表)
MySQL REVOKE实现删除用户权限
Jun 18 #MySQL
MySQL GRANT用户授权的实现
Jun 18 #MySQL
浅谈MySQL user权限表
Jun 18 #MySQL
解决mysql模糊查询索引失效问题的几种方法
Jun 18 #MySQL
You might like
PHP 处理图片的类实现代码
2009/10/23 PHP
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
常用的php图片处理类(水印、等比缩放、固定高宽)分享
2015/06/19 PHP
深入理解PHP中的count函数
2016/05/31 PHP
cakephp常见知识点汇总
2017/02/24 PHP
Django 中 cookie的使用
2017/08/17 PHP
js实现点小图看大图效果的思路及示例代码
2013/10/28 Javascript
多种方法实现load加载完成后把图片一次性显示出来
2014/02/19 Javascript
基于javascript的JSON格式页面展示美化方法
2014/07/02 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
2017/11/17 Javascript
vue获取元素宽、高、距离左边距离,右,上距离等还有XY坐标轴的方法
2018/09/05 Javascript
微信小程序视图控件与bindtap之间的问题的解决
2019/04/08 Javascript
jQuery创建折叠式菜单
2019/06/15 jQuery
mapboxgl区划标签避让不遮盖实现的代码详解
2020/07/01 Javascript
vue中defineProperty和Proxy的区别详解
2020/11/30 Vue.js
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
python共享引用(多个变量引用)示例代码
2013/12/04 Python
使用Python的PEAK来适配协议的教程
2015/04/14 Python
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
python读写配置文件操作示例
2019/07/03 Python
python中的列表与元组的使用
2019/08/08 Python
Python标准库shutil模块使用方法解析
2020/03/10 Python
浅析python 定时拆分备份 nginx 日志的方法
2020/04/27 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
Canvas在超级玛丽游戏中的应用详解
2021/02/06 HTML / CSS
凯蒂·佩里个人女鞋品牌:Katy Perry Collections
2019/04/04 全球购物
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
入党思想汇报怎么写
2014/04/03 职场文书
公司总经理任命书
2014/06/05 职场文书
幼儿园感恩节活动方案2014
2014/10/11 职场文书
一年级数学下册复习计划
2015/01/17 职场文书
结婚典礼主持词
2015/06/29 职场文书
反邪教学习心得体会
2016/01/15 职场文书