上节回顾:
1.建表语法:
注意点:
2.数据类型:
今日内容
1.表之间的关系
多对一,多对多,一对一
2.复制表
一个表中 要存储个人信息又要存储部门信息 会导致大量的数据冗余
所有数据存放在同一个表中 将导致以下几个问题
1.浪费空间 不致命
2.结构混乱
3.修改数据时 如果有一百个员工 那就要该一百次 扩展性极差
通过分表来解决
分表又造成新的问题 如何再将数据对应起来?
为什么需要对应起来是因为两张表的数据具备这某种关系
到底是什么关系呢?
多对一的关系
如何确定表之间的关系 需要从实际需求中分析
第一步:
从员工的角度来考虑
多个员工是不是可以属于同一个部门?
员工的多条记录是否对应部门的一条记录?
如果是 则可以确定 员工与部门是多对一
第二步:
从部门的角度来考虑
多个部门是不是可以有同一个员工?
员工部门多条记录是否对应员工的一条记录?
都不是 而是一个部门对应多个员工
也就是 部门与员工之间是一对多
最终我们发现 多个员工对应一个部门 一个部门对应多个员工
称之为单向多对一
如何在数据库中表示这种关系?
我们可以员工表中保存部门表的编号
问题:此时 我们的表之间存在关联但是是逻辑上的关联 并没有物理上的关联
换句话说 员工中可以插入不存在的部门编号
如何使其具备物理关联(硬性的关联)?
方案:
使用外键 foreign key
#创建表时:
create table dept(id,xxxxx);
create table emp(id,xxxxx,dept_id,foreign key(dept_id) references dept(id));
#后期修改:
alter table student add foreign key (id) references customer(id);
注意要建立外键关联,必须先创建主表
先有部门 后又员工 员工属于部门 部门拥有员工 所以 主表是部门 从表是员工
此时我们在执行添加 更新 删除时都会受到外键的约束
比如
1.员工表中添加一个不存在的部门id
2.修改某个部门的id
3.删除某个部门的数据
以上三种操作都会报错
1.必须已经存在的部门id才能出现在员工表中
2.无法修改 除非把员工全删掉
3.需要先删除员工 才能删除部门
处理起来都非常麻烦
能不能让主表和从表之间的更删除同步进行?
如果你是mysql开发者 你应不应该提供这样的功能?
必须的 这就是级联操作
有两种
指的是主表更新时 从表同步更新
指的是主表删除时 从表同步删除
语法:
create table emp(id,xxxxx,dept_id)foreign key(dept_id) references dept(id) on update cascade on delete cascade;
验证级联操作
实例分析 什么情况下会出现多对多的关系
学生表和老师表
多对多的关系本质上是什么?
是双向的多对一
如何在数据库中表示这种关系?
使用外键是不行的,需要创建第三张表专门用于存储关系
这个第三张表 如何体现关系?
在其中存储学生和老师的id即可 并且将它们作为外键关联到学生和老师表
create table t_s_relation(id int primary key auto_increment,t_id int,s_id int,foreign key(t_id) references teacher(t_id),foreign key(s_id) references stu(s_id));
为了去除重复的关系数据 可以给关系表添加主键约束 联合两个外键
实例分析:
客户表 与 学生表
一个客户对应一个学生 或没有成为学生
一个学生 必然只对应一个客户
如何表示这种对应关系 ?
使用外键
那么外键应该加到哪张表中呢?
因为是先有客户才有学生 所以 客户是主表 学生是从表 应该加在学生表中
我们已经知道一个学生只对应一个客户 ,但是有可能你写的时候写错了,写了一个重复的客户id
此时将会造成数据错乱 如何解决呢?
给外键字段再加上 唯一性约束
create table table_copy select *from t1;
复制数据和表结构,但不会复制key
只想要copy表结构怎么弄?
create table table_copy select *from t1 where 0 = 1;
给一个不成立的条件这样的话就查不到任何数据 ,只能复制表结构
蠕虫复制
insert into tablename(name) select name from tablename;
原文:https://www.cnblogs.com/yangyuanhu/p/11173481.html