12 外键、视图、事务
外键:foreign kye
外键:一张表(表1)中的其中一个字段,保存的值是另外一张表(表2)的主键,那么表1就是从表(具有外键的表),表2就是主表
外键表示了2张表中之间的联系,以另外一张表的外键作为主关键字的表是主表,具有此外键的表是主表的从表,设置了外键的表就是从表
外键字段必须保证要与其关联的主表的主键的数据类型完全一致、基本属性也要相同
比如:学生信息表student中的class_id就是外键,表student是从表,班级表class就是主表
新增外键
创建表的时候,新增外键
-- 语法
-- 在某个字段后,增加一条语句
-- [constraint `外键名`]可以省略,创建的时候会自动增加
[constraint `外键名`] foreign key('外键字段') references 主表(主表里面的主键)
-- 创建表的时候 添加外键
CREATE table foreignkey(
id int auto_increment PRIMARY key COMMENT '自增长主键',
name VARCHAR(10) not null COMMENT '姓名',
-- 关联 班级表 class
class_id int COMMENT '班级id',
-- 增加外键
FOREIGN key(class_id) REFERENCES class(id)
);
MUL:表示多索引,外键本身也是一个索引,一张表的索引可以大大提高表查询效率
查询表创建语句:
创建表后新增外键
-- 语法
alter table 从表 add [constraint `外键名`] foreign key(外键字段) references 主表(主表里面的主键)
-- 将表 student 中的字段 class_id 设置为外键
ALTER TABLE student add FOREIGN KEY(class_id) REFERENCES class(id);
删除外键
外键不允许修改,所以只能先删除再增加外键
-- 删除外键
-- 此处的外键名字,是 CONSTRAINT 后面的外键名字,可以通过 `show CREATE table student;` 查询
alter table 从表(有外键的表) drop foreign key 外键名字;
-- 删除表 student 中的 外键 class_id,注意此时 在创建外键时自动增加的普通索引 是不能删除的,所以在查看desc 表; 的时候 ,外键标记 MUL还是存在的
ALTER table student DROP FOREIGN key student_ibfk_1;
删除外键的时候,不能删除 在创建外键时自动增加的普通索引,只会删除外键自己本身,如果想要彻底删除自动增加的普通索引,可以使用下面的语法
ALTER table student DROP index 索引名字;
-- 删除普通索引
ALTER table student DROP index class_id;
外键约束
外键约束:通过建立外键关系后,对于主表和从表都会有一定的数据约束效率
1、 当一个外键产生时,外键所在的表(从表)会受制于主表中的数据,从而会导致有些数据不可以进行某些不符合规范的操作:比如从表不可以插入主表主键不存在的数据
外键约束其实主要约束的对象是主表,对于从表来说,主要约束的就是不能插入主表不存在的数据
-- 插入如下的数据就会报错:因为 在主表class中是没有主键id为10的班级信息的
INSERT INTO student VALUES(NUll,'王俊杰','男',DEFAULT,'睡觉',10,30);
SELECT * from student;
2、 如果一张表被其他外键引入,那么该主表的数据操作也会收到限制:必须保证从表数据的有效性,即不能随便删除被从表引入的那条记录
比如从表中(student表)有一个 学生是在4班的,那么班级信息表中的id=4的那条数据就不能随便删除
另外,我们在创建外键的时候,也是可以对外键约束进行选择性的操作的:
add [constraint `外键名`] foreign key(外键字段) references 主表(主表里面的主键) on update/delete 约束模式;
-- 约束模式主要分为下面3种
-- 1. district:默认严格模式,不允许操作
-- 2. cascade:级联模式,一起操作:主表变化,从表跟着一起变化
-- 3. set null:置空模式:主表记录删除后,从表对应的记录设置为null(前提是从表对应的外键字段允许为null)
视图
视图的本质就是虚拟表,所以关于表的一切操作都适用于视图
创建视图
视图的本质就是sql指令(select 语句)
-- 语法
-- select指令可以是单表数据、连接查询、联合查询后者子查询
create view 视图名 as select 指令;
-- 1. 创建视图
-- 因为student表中有id和name字段 class表中也有id和name字段,就是报错:- Duplicate column name 'id',此时就需要重命名相关字段
CREATE view student_class_v as
SELECT * from student s LEFT JOIN class c on s.class_id=c.id;
-- 正确的语句
CREATE view student_class_v as
SELECT s.*,c.id cid,c.name cname from student s LEFT JOIN class c on s.class_id=c.id;
查看视图结构
desc student_class_v;
show CREATE table student_class_v;
show CREATE VIEW student_class_v;
使用视图
视图就是一张虚拟表,可以直接把视图当做 '表' 操作,但是视图本身是没有数据的,视图中的数据是临时执行select 语句得到的对应结果;
视图主要是用于查询操作
修改视图
修改视图:就是修改视图所对应的查询语句
-- 语法:
alter view 视图名称 as 新的select语句;
删除视图
-- 语法
drop view 视图名称;
事务
事务是访问或可能更新数据库中各种数据项的一个程序执行单元(unit)
事务通常是由高级数据库操作语言或者编程语言书写的用户程序执行引起的
事务是由事务开始(start transaction)和事务结束(end transaction)之前执行的全体操作组成
基本原理
mysql允许将事务进行统一管理,将用户所做的操作暂时保存起来(保存到事务操作日志中),不直接更新到数据库表中,等到接收到新的事物操作执行后再执行操作,再将结果同步到数据库中
事务在mysql中通常是自动提交的,但是也可以手动提交事务
自动事务 autocommint
当客户端发送一条sql指令(写操作:增删改)给服务器的时候,服务器在执行后,不用等待用户反馈结果,会自动将结果同步到数据库
mysql默认是开启了自动事务的,主要通过变量 autocommit 控制的
-- 查看 事务
show VARIABLES like 'autocommit%';
关闭自动事务:关闭自动事务后,系统将不再自动帮助用户将数据自动更新到数据库中
set autocommit = 0;
-- 或者
set autocommit = off;
一般情况下,是不会关闭自动事务的,只会在需要使用事务的处理的时候,才会进行操作,一般还是手动事务
一旦自动事务关闭后,那么就需要用户自己提供是否需要同步的指令了:
commit:提交,同步到数据表,同时相关的事务日志文件被清空
-- 发送 commit 指令
commit;
rollback:回滚,清空之前的操作
-- 发送 rollback 指令
rollback;
手动事务
手动事务:不管是开始、过程、或者是结束,都需要操作者手动发送事务操作指令来执行事务
事务执行过程
-- 1. 开启事务:从这条语句开始,后面的语句都不会直接写入数据表,而是暂时保存在事务日志中
start transaction;
-- 2. 事务处理:一般是多个写指令执行:在此之前的所有操作,如果没有提交事务的话,另外的客户端都不会获取到最新的数据
增、删、改 操作
-- 3. 事务提交:至此所有的事务执行完毕
commit; -- 或者 rollback;
-- 1. 开启事务
START TRANSACTION;
-- 2. 执行事务
-- 一般是将多个连续但是是一个整体的sql指令,逐一执行
-- sql指令1:新增班级:六班
INSERT INTO class VALUES(NULL,'六班');
-- sql指令2:将id 为 2的学生划分到 六班
UPDATE student set class_id=6 WHERE id = 2;
-- 在此之前的所有操作,如果没有提交事务的话,另外的客户端都不会获取到最新的数据
-- 3. 提交事务:所有的客户端可以查询到最新的数据
commit;
回滚点
回滚点:当有一系列事务操作时,如果有其中一些事务没有执行成功,是没有必要将事务执行全部重新来过的,此时可以在某个成功的点设置一个记号:这个记号就是回滚点,然后如果后面有执行失败的地方,就可以回到这个记号位置,从回滚点重新执行
在一个事务处理过程中,可以设置多个回滚点,但是如果回到了前面的回滚点,那么后面的回滚点就失效了
-- 1. 增加回滚点
savepoint 回滚点名称;
-- 2. 回到回滚点
rollback to 回滚点名称;
设置回滚操作:
-- 将id为1的学生重命名为 '啦啦啦'
-- 1. 开启事务
START TRANSACTION;
-- 2. 新增班级7班
INSERT INTO class VALUES(NULL,'7班');
-- 查询结果
SELECT * from class;
-- 3. 设置回滚点
SAVEPOINT sp1;
-- 4. 将id为1的学生重命名为 '啦啦啦'
UPDATE student set name='啦啦啦' WHERE id = 9;
-- 更改数据错误,发现将id写成了9
SELECT * FROM student;
-- 5. 回到回滚点
ROLLBACK TO sp1;
-- 再次查询数据,数据恢复了
SELECT * FROM student;
-- 6. 重新 将id为1的学生重命名为 '啦啦啦'
UPDATE student set name='啦啦啦' WHERE id = 1;
SELECT * FROM student;
-- 7. 提交
commit;
事务特性:ACID
事务主要有4个主要特性:原子性、一致性、隔离性、持久性
原子性atomicity
一个事务是一个不可分割的工作单位,事务中的诸多操作要么都做,要么都不做
即:一个事务从开启事务start transtion起到commit或rollback提交,要么所有操作都成功、要么所有操作都失败
一致性consistency
事务必须是使数据库从一个一致性状态变到另一个一致性状态,一致性和原子性是密切相关的
即:数据表中的数据修改,要么是所有操作一次性修改,要么是全部不修改
隔离性isolation
一个事务的执行不能被其他事务干扰:即一个事务内部操作和使用的数据对并发的其他事务是隔离的,并发执行的各个职务之间不能互相干扰
即:一个客户端在使用事务操作一个数据的时候,另外一个客户端不可以同时对该相同的数据操作
持久性durability
也是永久性:是指一个事务一旦提交,它对数据库中的数据的改变就是永久性的
即: