(三十九)視圖,觸發器,事務
一、視圖
視圖是個虛擬表,只存在於內存中,但是它的表結構是存在於硬盤上的。為什麽要用視圖:使用視圖我們可以把查詢過程中的臨時表摘出來,保存下來,用視圖去實現,這樣以後再想操作該臨時表的數據時就無需重寫復雜的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. 而且有一個致命的問題:視圖是存放到數據庫裏的,如果我們程序中的
這麽多的弊端,為什麽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 過程名;
(三十九)視圖,觸發器,事務