表与表之间的三种关系
把所有数据都存放于一张表的弊端:
1、组织结构不清晰
2、浪费硬盘空间
3、扩展性极差
一、一对多:员工和部门
1、如何查找表与表之间的关系
以员工和部门表为例。查找表关系需要做到换位思考(站在两边去找表关系)
先站在员工表:
找员工表的多条数据能否对应部门表的一条数据
翻译:
多个员工能否属于一个部门
可以!之后不能直接下结论,还需要站在部门表的角度再确认关系
再站在部门表:
找部门表的多条数据能否对应员工表的一条数据
翻译:
多个部门能否有同一个员工
不可以!
只有站在两边表的角度都分析过了,才能够下结论
员工表单向多对一部门表
2、外键foreign key
①在创建表时,先建被关联的表dep,才能建关联表emp 先建被关联的表dep: create table dep( id int primary key auto_increment, dep_name char(16), dep_desc char(64) ); 再建关联表emp: create table emp( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', # default后面的默认值空格直接书写即可 dep_id int, foreign key(dep_id) references dep(id) ); ②在插入数据时,必须先插入被关联的表dep,在插入关联表emp 先插入被关联的表dep: insert into dep(dep_name,dep_desc) values ('外交部','形象代言人'), ('教学部','教书育人'), ('技术部','技术能力有限部门'); 再插入关联的表emp: insert into emp(name,gender,dep_id) values ('jason','male',1), ('egon','male',2), ('kevin','male',2), ('tank','male',2), ('jerry','female',3); update dep set id=100 where id=2; 会报错 delete from dep where id=100; 会报错 当我想修改emp里的dep_id或dep里面的id时返现都无法成功 当我想删除dep表的教学部的时候,也无法删除 方式1:先删除教学部对应的所有的员工,再删除教学部 方式2:受限于外键约束,导致操作数据变得非常复杂,能否有一张简单的方式, 让我不需要考虑在操作目标表的时候还需要考虑 关联表的情况,比如我删除部门,那么这个部门对应的员工就应该跟着立即清空
3、怎么解决可以修改emp里的dep_id或dep里面的id(给外键字段新增功能:同步更新同步删除(级联删除级联更新)):
先把之前创建的表删除,先删员工表,再删部门表,最后按章下面的方式重新创建表关系
先建被关联的表dep: create table dep( id int primary key auto_increment, dep_name char(16), dep_desc char(64) ); 在建关联表emp: create table emp( id int primary key auto_increment, name char(16), gender enum('male','female','others') not null 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(name,gender,dep_id) values ('jason','male',1), ('egon','male',2), ('kevin','male',2), ('tank','male',2), ('jerry','female',3); update dep set id=100 where id=2; # 把dep表中字段id是2的改成100 delete from dep where id=100; # 把dep表中字段id是100的删除
二、多对多:图书和作者
1、如何查找表与表之间的关系
仍然站在两张表的角度:
站在图书表:一本书可不可以有多个作者,可以!那就是书多对一作者
站在作者表:一个作者可不可以写多本书,可以!那就是作者多对一书
双方都能一条数据对应对方多条记录,这种关系就是多对多!
先来想如何创建表?图书表需要有一个外键关联作者,作者也需要有一个外键字段关联图书。问题来了,先创建谁都不合适!如何解决?
建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id
2、外键foreign key
创建book表: create table book( id int primary key auto_increment, title char(16), price int ); 创建author表: create table author( id int primary key auto_increment, name char(16), gender char(16) ); 创建book2author表: create table book2author( id int primary key auto_increment, book_id int, author_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 ); 表book中插入数据: insert into book(title,price) values ('金青梅','100'), ('围城','200'), ('python全栈开发','3000'); 表author中插入数据: insert into author(name,gender) values ('jason','male'), ('egon','female'), ('kevin','male'); 表book2author中插入数据: insert into book2author(book_id,author_id) values (1,1), (1,2), (1,3), (2,1), (2,3), (3,1), (3,2);
三、一对一:客户表和学生表
左表的一条记录唯一对应右表的一条记录,反之也一样
创建顾客表: create table customer( id int primary key auto_increment, name char(16) not null, qq char(16) not null, phone char(16) not null ); 创建学生表: create table student( id int primary key auto_increment, class_name char(20) not null, customer_id int unique, foreign key(customer_id) references customer(id) on delete cascade on update cascade );
总结:三种外键关系都是用foreign key,区别在于如何使用以及其他条件限制即可做出三种关系
四、修改表
①修改表名
alter table 表名 rename 新表名;
②增加字段
alter table 表名 add 字段名 数据类型[完整性约束条件];
add 字段名 数据类型[完整性约束条件];
alter table 表名 add 字段名 数据类型[完整性约束条件] first;
alter table 表名 add 字段名 数据类型[完整性约束条件] after 字段名;
③删除字段
alter table 表名 drop 字段名;
④修改字段:modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
alter table 表名 modify 字段名 数据类型[完整性约束条件];
alter table 表名 change 旧字段名 新字段名 旧数据类型[完整性约束条件];
alter table 表名 change 旧字段名 新字段名 新数据类型[完整性约束条件];
五、复制表
①复制表结构+记录 (key不会复制: 主键、外键和索引) create table new_service select * from service; ②只复制表结构 create table new1_service select * from service where 1=2; 条件为假,查不到任何记录