1. 多表关联
为什么需要多个表?
更好更精确的描述数据,但有时一个表里的字段太多,数据太大,查起来不方便,所以我们可以分表
分表的原因?
重复数据浪费空间 2.数据的结构混乱3.数据的扩展性,维护性差
分表导致的问题?
表1中可能存储了表2中不存在的数据,这样整个数据就不完整了,是一组无效的数据
解决的方案?
外键约束:为多个表之间建立联系
语法:
Create table t(字段名 类型),foreign key(要关联的字段名) refrences t1 (主键名)
多表之间的关系:
一对多,多对多,一对一
一对多的情况:
例子:一家公司的部门与员工
Create table dept (id int primary key auto_increment,name char(20),job char(20));
Create table emp (id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept (id));
从这个例子我们可以知道两个之间是有主从关系的,所以我们在使用外键时,一定要注意主从关系
外键的约束:
- 要先创建主表 再创建从表
- 插入记录时,要先插入主表,再插入从表
- 删除记录时,要先删除从表记录,在删除主表记录
- 从表更新外键时,必须保证外键的存在
- 更新主表id时,必须先删除从表关联的数据 或把关联的数据关联到主表的其他id上
- 删除主表时,要先删除从表
由于外键的约束会导致:我们就删除主表的一条记录,就会出现问题
解决方案:使用级联
Create table dept (id int primary key auto_increment,name char(20),job char(20));
Create table emp (id int primary key auto_increment,name char(20),d_id int,foreign key(d_id) references dept (id) on delete cascade on update cascade);
on delete cascade 删除主表记录时,从表的相关记录同步删除
on update cascade更新主表记录时,从表的相关记录同步更新
注意是单向的 主表变化是 级联操作从表 从表的变化不会级联到主表
多对多情况时:
例子:老师和学生
一个老师可以教多个学生
一个学生可以被多个老师教
这样用上面的方法就不对了,我们需要一个中间表 专门存储关联关系
create table teacher(id int primary key auto_increment,name char(15));
create table student(id int primary key auto_increment,name char(15));
中间表
create table tsr(id int primary key auto_increment,
t_id int,s_id int,foreign key(t_id) references teacher(id),
foreign key(s_id) references student(id));
现在老师和学生 都是主表 关系表是从表
相当于2个一对多
插入数据和一对多一样,先插主表,再查从表
先插入老师和学生数据
一对一情况时: 和一对多一样
使用场景: 当一个表这种字段太多 而常用字段不多时?
- 可以采取垂直分表的方式来提高效率
- 可以采取水平分表 字段完全相同 即分成2个表(字段一样的表)
比如:原有的person表 可以查成2个关联的表
2.表的应用
1.修改表
alter table 表名+
add 添加字段 after|first
after 添加字段到哪个字段后面
first 添加字段到最前面
modify 修改字段类型
change 修改字段名称 或 类型
drop 删除字段
rename 改表名
2.复制表
create table 新的表名 select * from 原表名;
数据
结构
约束不能复制
当条件不成立是 只复制表结构
create table 新的表名 select * from 原表名 where 1 = 2;
create table stu_copy2 select * from student1 where 1 = 2;
3.蠕虫复制
自我复制
insert into 表名称 select *from 表名;
如果有主键 避开主键字段
insert into 表名称(其他字段) select 其他字段 from 表名;
sql注入攻击
一个了解sql语法的攻击者 可以在输入框输入sql语句
132456789 123
select *from user where account = ":"drop database mysql" and pwd = "123";