Mysql系列之六(檢視,事務,觸發器等)
阿新 • • 發佈:2021-01-10
檢視
1.什麼是檢視
檢視就是通過查詢一張表儲存起來,下次可以接著用
2.為什麼要用檢視
如果要頻繁的使用一張虛擬表,你可以製作成檢視,後續直接使用
3.如何操作
# 固定語法
create view 視圖表明 as sql語句獲得的虛擬表
具體操作
# 具體操作
create view teacher2course as
select * from teacher INNER JOIN course
on teacher.tid = course.teacher_id
;
注意
1.檢視建立在硬盤裡只有表結構,資料並沒有寫入硬碟 2.檢視只能用來檢視,如果對檢視的資料進行修改則可能會影響原始表中的資料 3.檢視不方便維護 綜上:檢視很少使用
觸發器
什麼是觸發器
觸發器是指在對資料進行增刪改查操作的基礎上,自動觸發的功能
主要用於:日誌記錄監控等方面
主要有以下的幾種組合
before/after delete/update/insert
觸發器的具體用法
# 固定語法 create trigger 觸發器的名字 before/after delete/update/insert on 表名 for each row begin sql語句 end # 針對命名 要見名知意,如 tri_bef_del_student # 增對;問題 由於在定義觸發器的過程中需要用;來明確語意,所以通常在使用前後更改。 方法: delimiter \\ delimiter ;
觸發器的例項式**
# 案例 CREATE TABLE cmd ( id INT PRIMARY KEY auto_increment, USER CHAR (32), priv CHAR (10), cmd CHAR (64), sub_time datetime, #提交時間 success enum ('yes', 'no') #0代表執行失敗 ); CREATE TABLE errlog ( id INT PRIMARY KEY auto_increment, err_cmd CHAR (64), err_time datetime ); """ 當cmd表中的記錄succes欄位是no那麼就觸發觸發器的執行去errlog表中插入資料 NEW指代的就是一條條資料物件 """ delimiter $$ create trigger tri_after_insert_cmd after insert on cmd for each row begin if NEW.success = 'no' then insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time); end if; end $$ delimiter ; # 朝cmd表插入資料 INSERT INTO cmd ( USER, priv, cmd, sub_time, success ) VALUES ('jason','0755','ls -l /etc',NOW(),'yes'), ('jason','0755','cat /etc/passwd',NOW(),'no'), ('jason','0755','useradd xxx',NOW(),'no'), ('jason','0755','ps aux',NOW(),'yes'); # 刪除觸發器 drop trigger tri_aft;
事務(**)
1.什麼是事務
事務是指在資料在多條資料一起操作的過程中,要麼都成功,要麼都失敗
2.事務的四大特性
ACID四大特性
1.原子性
原子性是指將一個事務作為原子,整體操作,一個失敗則全體失敗
2.一致性
一致性是指事務從一個狀態到另外一個狀態,與原子性精密相連
3.隔離性
隔離性是指事務與事務之間不受干擾
4.永續性
永續性是指事務結束後,資料更改應該是永久性的,而不是短暫的
事務的用法
1.開啟事務
start transaction;
2.回滾操作(回到事務之前的操作)
rollback;
3.確認(確認之後就無法回滾)
commit
"""模擬轉賬功能"""
create table user(
id int primary key auto_increment,
name char(16),
balance int
);
insert into user(name,balance) values
('jason',1000),
('egon',1000),
('tank',1000);
# 1 先開啟事務
start transaction;
# 2 多條sql語句
update user set balance=900 where name='jason';
update user set balance=1010 where name='egon';
update user set balance=1090 where name='tank';
"""
總結
當你想讓多條sql語句保持一致性 要麼同時成功要麼同時失敗
你就應該考慮使用事務
"""
儲存過程
什麼是儲存過程
儲存過程就是講各種執行封裝成函式,以供呼叫
基本使用
定義:
create procedure 名稱(
in m int #只接受資料,
out n int #輸出資料,
inout b int #即輸出有接受
)
begin
sql程式碼;
end;
呼叫:call p1(引數)
三種開發模式
第一種
"""
應用程式:程式設計師寫程式碼開發
MySQL:提前編寫好儲存過程,供應用程式呼叫
好處:開發效率提升了 執行效率也上去了
缺點:考慮到認為元素、跨部門溝通的問題 後續的儲存過程的擴充套件性差
"""
第二種
'''
應用程式:程式設計師寫程式碼開發之外 設計到資料庫操作也自己動手寫
優點:擴充套件性很高
缺點:
開發效率降低
編寫sql語句太過繁瑣 而且後續還需要考慮sql優化的問題
'''
第三種
"""
應用程式:只寫程式程式碼 不寫sql語句 基於別人寫好的操作MySQL的python框架直接呼叫操作即可 ORM框架
優點:開發效率比上面兩種情況都要高
缺點:語句的擴充套件性差 可能會出現效率低下的問題
"""
儲存過程具體演示
delimiter \\
create procedure p1(
in m int,
in n int,
out res int
)
begin
select * from cmd where id > m and id <n;
set res = 666;
end \\
delimiter ;
注意:在Mysql客戶端使用的話必須要先定義一個變數res,輸出的時候才能有變數名繫結
定義語法:
set @res = 0;
呼叫語法:
select @res;
在pymysql中如何呼叫儲存過程
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123456',
database='day49',
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
res = cursor.callproc('p1', (10, 14, 666))
cursor.featchall() # 有返回值
'''
這裡pymysql模組自動對傳入的值進行了變形操作
@_p1_0
@_p1_1
@_p1_2
'''
cursor.execute('select @_p1_2')
# [{'@_p1_2': 666}]
print(cursor.fetchall())
函式
函式就是mysql內建的一些功能,通過關鍵字()的方式可以呼叫
NOW()方法
('jason','0755','ls -l /etc',NOW(),'yes')
CREATE TABLE blog (
id INT PRIMARY KEY auto_increment,
NAME CHAR (32),
sub_time datetime
);
INSERT INTO blog (NAME, sub_time)
VALUES
('第1篇','2015-03-01 11:31:21'),
('第2篇','2015-03-11 16:31:21'),
('第3篇','2016-07-01 10:21:31'),
('第4篇','2016-07-22 09:23:21'),
('第5篇','2016-07-23 10:11:11'),
('第6篇','2016-07-25 11:21:31'),
('第7篇','2017-03-01 15:33:21'),
('第8篇','2017-03-01 17:32:21'),
('第9篇','2017-03-01 18:31:21');
select date_format(sub_time,'%Y-%m'),count(id) fr
流程控制
例如python中的if,while迴圈在mysql中也有固定的語法
# if判斷
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN
declare i int default 0;
if i = 1 THEN
SELECT 1;
ELSEIF i = 2 THEN
SELECT 2;
ELSE
SELECT 7;
END IF;
END //
delimiter ;
# while迴圈
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN
DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
SELECT....
num ;
SET num = num + 1 ;
END WHILE ;
索引
資料存放在硬碟中,當我們查詢資料時候不得不與硬碟打交道,那麼就必須要進行IO操作。
索引:類似於書的目錄,是一種資料結構,是用來加速資料的查詢的。
索引在MySQL中也叫'鍵',主要有以下三種:
primary key
unique key
index key
注意foreign key不是用來加速查詢用的,不在我們的而研究範圍之內
上面的三種key,前面兩種除了可以增加查詢速度之外各自還具有約束條件,而最後一種index key沒有任何的約束條件,只是用來幫助你快速查詢資料
本質
我們原來查詢資料是一頁一頁的找,沒有目的性,
而索引則形成了一種固定的機制來幫助我們查詢資料。
索引的優缺點
'''
在同一個表中可以有多個不同的索引,但是我們不是每一個欄位都需要加上索引
'''
'''
索引的優缺點:
優點:
· 能夠加速查詢的順序
缺點:
· 當列表中已經存在大量資料的情況下,建立索引需要的時間很長
· 當我們更改資料時,那麼原來的索引失效,所以會在我們更改資料的同時建立索引,使我們對錶修改的速度大大降低
'''
b+樹
b+樹是一種資料查詢機制
通過多分法將資料分為幾個範圍,逐漸縮小查詢,
注意:在體幹上存放的是虛擬資料,只有葉子(最底層存放了真實的資料)
為什麼會將id列通常作為主鍵?
因為id列站硬碟空間小,在同一個block中存放的資料更多,這樣b+樹的層級低,速度更快
聚集索引
聚集索引就是指主鍵
primary key
輔助索引(unique,index)
查詢資料的時候不可能一直使用主鍵,有時我們需要用其他的列,給其他的列建立索引
'''
注意:
在輔助索引中存放的是主鍵的id號
拿到id號後還要在聚合索引中進行查詢
'''
覆蓋索引
'''
是指所查詢的資料就是在索引列,那麼此時會直接返回資料,不要再次查詢(在輔助索引的葉子節點就已經拿到了需要的資料)
'''
# 給name設定輔助索引
select name from user where name='jason';
# 非覆蓋索引
select age from user where name='jason';