8.20MySQL(三)外键
作者:互联网
一、外键前戏
1.定义一张部门员工表
2.把所有数据都存放于一张表的弊端
1.表的结构不清晰
2.浪费硬盘空间
3.表的扩展性极差(无法忽略的缺点)
3.上述的弊端产生原因类似于把代码全部写在一个py文件中,你应该怎么做?
解耦合!将上述一张表拆成员工和部门两张表!
4.分析表数据之间的关系:
多个用户对应一个部门,一个部门对应多个用户。禁止一个用户对应多个部门这种情况是另外一张表关系
5.如何确立表与表之间的关系
一定要换位思考(必须两方都考虑周全之后才能得出结论)
以员工表和部门表为例:
先站在员工表看能否有多个员工对应一个部门 翻译过来: 一个部门能否有多个员工 可以!!!(暂时只能确定员工单向多对一部门)
再站在部门表看能否有多个部门对应一个员工 翻译过来: 一个员工能否属于多个部门 不可以!!!
结论:员工表和部门表之间仅仅是单向的多对一
那么它们的表关系就是"一对多"
表关系中没有多对一这一说,只有一对多
无论是多对一还是一对多都叫"一对多"
二、外键:foreign key
如何让两种表有代码层面上真正的关联,就必须使用外键
1.什么是外键?
让表与表有硬性层面上的关系
2.关键字:
foreign key
三、一对多外键建立
1.建表
先创建被关联表,否则会报错
create table dep( id int primary key auto_increment, dep_name varchar(32), dep_desc varchar(128) );
create table emp( id int primary key auto_increment, emp_name varchar(64), emp_gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) );
再插入数据,也必须先插入被关联表的数据
insert into dep(dep_name,dep_desc) values('外交部','搞外交'), ('教学部','教书育人'), ('技术部','技术能力有限部门');
insert into emp(emp_name,dep_id) values('jason',1), ('egon',2), ('tank',2), ('kevin',3);
外键约束:
1.在创建表的时候,必须先创建被关联表
2.插入数据的时候,也必须先插入被关联表的数据
2.修改表数据
update dep set id=200 where id = 1; # 无法修改
update emp set dep_id = 300 where id = 1; # 也无法修改
删除数据也同样不行
外键虽然能够帮你强制建立表关系,但是也会给表之间增加数据相关的约束
3.如何才能删除
1.删除数据的时候,先删员工表的数据,再删部门表的数据
delete from emp where id = 4;
delete from dep where id = 3;
2.级联更新:on update cascade,级联删除:on delete cascade
更新部门后,对应员工表中的标示部门的字段同步更新
删除部门后,对应的部门里面的员工表数据对应删除
# 先创建被关联表 create table dep( id int primary key auto_increment, dep_name varchar(32), dep_desc varchar(128) ); create table emp( id int primary key auto_increment, emp_name varchar(64), emp_gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) on update cascade # 级联更新 on delete cascade # 级联删除 ); # 先插入被关联表的数据 insert into dep(dep_name,dep_desc) values('外交部','搞外交'), ('教学部','教书育人'), ('技术部','技术能力有限部门'); insert into emp(emp_name,dep_id) values('jason',1), ('egon',2), ('tank',2), ('kevin',3); update dep set id=200 where id = 3; # 修改被关联表的数据成功 delete from dep where id = 2; # 删除被关联表的数据成功
四、多对多关系的建立
1.图书与作者表(一定要换位思考):
先站在图书
多本书能否有一个作者
一个作者能否写多本书,可以!!!
再站在作者
多个作者能否和写一本书
一本书能否有多个作者,可以!!!
如果双方都是可以,那么就是多对多
强调:foreign key 只是用来帮你建表关系的,不是某个关系特有的方法
2.多对多关系的建立
必须手动创建第三张表,用来专门记录两张表之间的关系
先建两张普通的表,不需要设置外键
create table book( id int primary key auto_increment, title varchar(32), price int ); create table author( id int primary key auto_increment, name varchar(32), age int );
再创建第三张表,用来专门记录两张表之间的关系
create table book2author( id int primary key auto_increment, book_id int, foreign key(book_id) references book(id) on update cascade on delete cascade, author_id int, foreign key(author_id) references author(id) on update cascade on delete cascade );
插入数据
insert into book(title,price) values('西游记',199),('聊斋',299),('jason教你删别人的库,让别人跑路',1); insert into author(name,age) values('jason',18),('tank',38); insert into book2author(book_id,author_id) values(4,3); # 报错,必须要在两张表的id范围里 insert into book2author(book_id,author_id) values(1,1),(1,2),(2,1),(3,1),(3,2);
五、一对一表关系的建立
1.一对一表关系
1.一对一的场景:当你的表特别庞大的时候,你可以考虑拆分表
2.联想老男孩的客户和学生(老男孩的客户与学生之间,报名之前都是客户,只有报了名的才能是学生)
当你没有交学费之前,你是老男孩的客户
当你交了学费之后,你就变成老男孩的学生
是所有的客户都能变成学生吗?
2.通常将关系字段,称之为:外键字段
一对多的外键字段,建在多的一方
多对多的外键字段,建在第三张表
一对一的外键字段,建在任意一方都可以,但是推荐你建在查询频率较高的一方
3.建立
# 先创建被关联表 create table authordetail( id int primary key auto_increment, phone int, addr char(255) ); create table author( id int primary key auto_increment, name char(4), age int, authordetail_id int unique, foreign key(authordetail_id) references authordetail(id) on update cascade on delete cascade );
六、判断表关系的最简单的语法
图书与出版社
一本书可不可以有多个出版社 不可以!!!
一个出版社可不可以出版多本书 可以!!!
一对多的关系
图书与作者
一本书可不可以有多个作者 可以!!!
一个作者可不可以写多本书 可以!!!
多对多的关系
作者与作者详情
一个作者可不可以有多个详情 不可以!!!
一个作者详情可不可以有多个作者 不可以!!!
要么两者是一对一
要么两者之间没任何关系
七、了解知识点
1.修改表的完整语句
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST; # 直接移到最前面
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名; # 选择插哪个字段的后面
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段 # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];
2.复制表
# 查询语句执行的结果也是一张表,可以看成虚拟表
# 复制表结构+记录 (key不会复制: 主键、外键和索引)
create table new_service select * from service;
# 只复制表结构
select * from service where 1=2; //条件为假,查不到任何记录
create table new1_service select * from service where 1=2;
create table t4 like employees;
标签:dep,外键,int,8.20,emp,key,MySQL,id 来源: https://www.cnblogs.com/francis1/p/11384277.html