一、视图
视图是个虚拟表,只存在于内存中,但是它的表结构是存在于硬盘上的。为什么要用视图:使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用。
- 创建视图
create view t1_view as select *from t1;
Create view 视图名 as sql语句;
- 修改表内容
update t1 set age=88 where id = 4;
- 插入数据
insert into t1_view(name,age) values('mm',67),('uiui',90);
- 删除视图
drop view t1_view;
drop view 视图名;
- 修改视图
alter view tt_view as select *from t2;
alter view 视图名 as 新sql语句;
#!!!注意注意注意:
#1. 使用视图以后就无需每次都重写子查询的sql,开发的时候是方便了很多,但是这么效率并不高,还不如我们写子查询的效率高
#2. 而且有一个致命的问题:视图是存放到数据库里的,如果我们程序中的sql过分依赖于数据库中存放的视图,那么意味着,一旦sql需要修改且涉及到视图的部分,则必须去数据库中进行修改,然后再到自己的应用程序里面将那个sql语句改一改,需要很多的修改工作,并而对视图的更改通常在一般中型及以上公司中数据库有专门的DBA负责,你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便
这么多的弊端,为什么mysql还要提供这个东西呢,有一点是因为mysql想把所有数据处理的工作全部接手过来,但其实还有其他的原因,等我们讲完存储过程在和大家说吧。
#3 并且注意:视图一般都是用于查询,尽量不要修改(插入、删除等)视图中的数据,虽然有时候可以修改成功,但是尽量不要这样做,因为这个视图可能是多个表联合起来生成的一个结果,如果你修改它,可能会造成很多表里面的数据都跟着被修改了
小总结:单表查询时,可以对表实现插入和修改,但是联表时,可以插入,但不能修改。插入数据时,values()括号内写的哪个表的字段,那么就就会给哪个表插入数据。
二、触发器
实现对一张表操作前或者后,进行一些其他的操作。触发器是被动调用的,并且会一直伴随这张表。
表1--t1
Id name age
表2--t2
Id content tid(这个是t1表的id)
Delimiter //#重新声明一个结束符
Create trigger tri_1 after(befor) insert(update,delete) on t2 for each row #创建一个触发器,没有结束符
If new.tid > 5 then #使用if判断
Insert into t1(name,age) values(‘uuuu’,new.tid);#对t2操作完后,对t1进行的操作
End if;# if操作结束
End // #触发器内容执行完毕
Delimiter ;#把结束符再声明回分号“;”
删除触发器:
drop trigger 触发器名字;
三、事务
把多个sql语句绑定在一起执行,并且其中某个没有执行成功,只要没有commit,就还可以回滚rollback。
start transaction;
insert into t1(name,age) values('11211aaaaa',24);
insert into t3(name,age) values('bbbbbbb',67);#实际没有t3表,所以会报错
insert into t2(content,tid) values('ccccccc', 13);
上面第二条插入数据的sql语句报错,所以rollback回滚一下,回到原来的数据。
四、存储过程
把sql语句做成一个过程,这样方便程序员调用。存储过程有其自己的优缺点:
优点:
#1. 用于替代程序写的SQL语句,实现程序与sql解耦
#2. 基于网络传输,传别名的数据量小,而直接传sql数据量大
缺点:
#1. 程序员扩展功能不方便
- 创建无参存储过程
delimiter // #声明一个结束符
create procedure p1() #创建一个存储过程
Begin #开始
select *from t1;#过程中执行的sql语句
insert into t2(content,tid) values('9090ooiioijkkj',6);#过程中执行的sql语句
end // #执行完毕
delimiter ; #把结束符重新声明回“;”
- 创建有参数的存储过程
delimiter // #声明一个新的结束符
create procedure p5(
in arg1 int,
out arg2 char,
inout arg3 int
) #创建一个存储过程
Begin#过程开始执行
select *from t1 where name='tom'; #过程中的sql语句
select *from t1 where id > arg1; #过程中的sql语句
insert into t1(name,age) values('Moon',27); #过程中的sql语句
set arg2 = 'finish';#为out类型的变量重新赋值
set arg3 = 20; #为inout类型的变量重新设置值
end // #过程执行完毕
delimiter ; #把结束符重新声明回来
set @res1='tom'; #创建一个变量
set @res2=10; #创建一个变量
call p2(2,@res1,@res2); #调用存储过程
select @res1; #查询out类型的值被修改为什么了
select @res2; #查询inout类型的值被修改为什么了
- 删除存储过程
Drop procedure 过程名;