外键一对一,一对多,多对多表关系
表与表之间建立关系:
把所有数据都存放于一张表的弊端
1.组织结构不清晰
2.浪费硬盘空间
3.扩展性极差
查找表关系一定要换位思考,就是要站在两张表角度全部考虑完毕才能下结论,
否则无法的出正确答案。单向的多对一,就是一对多的外键关系。
一对多:
简单举个例子:比如说一个公司里面有很多部门,而且有很多员工分别在不同的部门里,
我们可以先站在员工的角度看是否能多个员工同属于一个部门:也就是说一个部门是否有多个员工?
当然是可以的。这里我们确定了员工是单向多对一个部门的。
再站在部门的角度来看能否可以有多个部门对应一个员工?显然是不可以的。
总结一下就是员工和部门之间关系如果仅仅是单向的多对一那么他们的表关系就是一对多。
什么是外键?
外键就是让表与表之间有硬性层面上的关系,而不是你说它们有关系它们就有关系了。
如何让两种表有代码层面上真正的关联:
就得使用外键,外键语法:foreign key
一对多建立表关系:
外键约束:
在创建表的时候 必须先创建被关联表。
插入数据的时候 也必须先插入被关联表的数据。
建表:
复制代码
部门表:
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, # id相当于主键,并且自动递增
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('员工1',1),
('员工',2),
('员工3',2),
('员工4',3);
复制代码
修改表数据:
外键虽然能够帮你强制建立表关系 但是也会给表之间增加数据相关的约束;改也不好改,删也不好删。
删除的时候可以先删除把绑定关系表的数据,然后再删除被绑定关系表的数据。现在绑定关系
表是emp,被绑定关系表是dep;删除语句为:
delete from emp where id = 4;
delete from dep where id = 3;
但是这样修改太麻烦,当你要修改表中的某一条数据时,还要考虑先改哪张表再改哪张表。
第二种修改方式:
级联更新级联删除:就是你在建外键的时候可以告诉它,之后你在动外键数据的时候我们两者是同步的,
你怎么动我怎么动,你删一条数据,我也跟着删除一条数据;你变我也跟着你变。
级联更新级联删除建表:
复制代码
被关联表
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('员工1',1),
('员工2',2),
('员工3',2),
('员工4',3);
同步更新数据:
update dep set id=200 where id = 3;
同步删除数据
delete from dep where id = 2;
复制代码
多对多表关系:
如果两边都是单向的多对一,那么两者就是多对多关系。比如说书和作者的关系:
先站在图书的角度看多本书能否有一个作者 就是一个作者能否写多本书?当然是可以的!
再站在作者看多个作者是否能共写一本书 就是一本书能否有多个作者 可以!!!
如果双方都是可以,那么就是多对多
需要注意的是 foreign key只是用来帮你建表关系的 不是某个关系特有的方法
建表:
复制代码
需要注意的是 多对多关系的建立 必须手动创建第三张表 用来专门记录两种表之间的关系
# 先建两种普通的表 不需要设置外键
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),('python',999)
insert into author(name,age) values('jack',18),('ross',38);
关系表数据插入:
insert into book2author(book_id,author_id) values(1,1),(1,2),(2,1),(3,1),(3,2);
一对一表关系:
一对一的场景 当你的表特别庞大的时候 你可以考虑拆分表;联想老男孩的客户和学生:
当你没有交学费之前 你是老男孩的客户当你叫了学费之后 你就变成老男哈的学生,并不是所有的客户都能变成学生。
如果两者之间的一对多都不成立,那么两者之间只有两种情况了
要么是一对一的关系,要么他们根本没有关系。
通常将关系字段 称之为 外键字段:
一对多的外键字段 建在多的一方
多对多 建在第三张表了
一对一 外键字段建在任意一方都可以 但是推荐你建在查询频率较高的一方
建表:
复制代码
create table authordetail1(
id int primary key auto_increment,
phone int,
addr char(255)
);
create table author1(
id int primary key auto_increment,
name char(4),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail1(id)
on update cascade
on delete cascade
);
插入数据
insert into authordetaill(python,add) values(123,'China'),(321,'USA'),(111,'Africa')
insert into author1(nsme,age,authordetail_id),('jack',18,1),('roos',38,2)
删除数据
delete from authordetaill where id = 1;
复制代码
表关系总结:
判断表关系的最简单的语法
图书与出版社
一本书可不可以有多个出版社 不可以!!!
一个出版社可不可以出版多本书 可以!!!
一对多的关系
图书与作者表
一本书可不可以有多个作者 可以!!!
一个作者可不可以写多本书 可以!!!
多对多的关系
作者与作者详情
一个作者可不可以有多个详情 不可以!!!
一个作者详情可不可以有多个作者 不可以!!!
要么两者是一对一
要么两者之间没任何关系
了解知识点:
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 旧字段名 新字段名 新数据类型 [完整性约束条件…];
查询语句执行的结果也是一张表,可以看成虚拟表
复制表结构+记录 (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;