一、视图

视图是个虚拟表,只存在于内存中,但是它的表结构是存在于硬盘上的。为什么要用视图:使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用。

  1. 创建视图

        create view t1_view as select *from t1;

        Create  view 视图名 as  sql语句;

  1. 修改表内容

     update t1  set age=88 where id = 4;

  1. 插入数据

     insert into t1_view(name,age) values('mm',67),('uiui',90);

  1. 删除视图

       drop  view  t1_view;

       drop  view  视图名;

  1. 修改视图

   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. 程序员扩展功能不方便

 

  1. 创建无参存储过程

  

delimiter //   #声明一个结束符

create procedure p1()   #创建一个存储过程

Begin  #开始

select *from t1;#过程中执行的sql语句

insert into t2(content,tid) values('9090ooiioijkkj',6);#过程中执行的sql语句

end // #执行完毕

delimiter ;  #把结束符重新声明回“;

 

  1. 创建有参数的存储过程

 

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类型的值被修改为什么了

 

  1. 删除存储过程

  Drop procedure 过程名;