視圖就是將SQL語句的查詢結果獲得的一張虛擬表,保存下來僅保留表結構,這張虛擬表就是視圖python
爲了便於後期直接查詢,節省拼接表的時間消耗mysql
語法:create view 視圖名 as sql語句sql
create view class_student as select * from class inner join student on class.cid = student.class_id;
注意:一、建立出來的視圖只有表結構,沒有表數據,數據仍是源於原來的表數據庫
二、不要修改視圖中的數據,會直接影響原表中的數據,視圖只用於查詢安全
通常開發工做中,不用視圖,由於後期想拓展功能,會須要對視圖進行修改,意味着你須要先在mysql視圖修改而後再去程序中修改,須要跨部門溝通,全部通常不用視圖數據結構
在對某張表的數據進行增、刪、改的一些操做下,自動觸發的,稱之爲觸發器函數
在對一張表數據進行增insert、刪delete、改update時,一旦有這種行爲,就會觸發觸發器去執行一段SQL代碼優化
能夠對增/刪/改,前/後 觸發觸發器ui
完整語法:create trigger 觸發器名字 before/after insert/delete/update for each row begin sql語句... end
注意:觸發器名字,命名規範最好使用下劃線體,而且見名知意,如:tri_before_insert_t1日誌
delimiter $$ # 將mysql默認的結束符由;換成$$
# 針對插入 create trigger tri_after_insert_t1 after insert on 表名 for each row begin sql代碼。。。 end create trigger tri_before_insert_t2 before insert on 表名 for each row begin sql代碼。。。 end # 針對刪除 create trigger tri_after_delete_t1 after delete on 表名 for each row begin sql代碼。。。 end create trigger tri_before_delete_t2 before delete on 表名 for each row begin sql代碼。。。 end # 針對修改 create trigger tri_after_update_t1 after update on 表名 for each row begin sql代碼。。。 end create trigger tri_before_update_t2 before update on 表名 for each row begin sql代碼。。。 end # 案例 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 ); delimiter $$ # 將mysql默認的結束符由;換成$$ create trigger tri_after_insert_cmd after insert on cmd for each row begin if NEW.success = 'no' then # 新記錄都會被MySQL封裝成NEW對象 insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time); end if; end $$ delimiter ; # 結束以後記得再改回來,否則後面結束符就都是$$了 #往表cmd中插入記錄,觸發觸發器,根據IF的條件決定是否插入錯誤日誌 INSERT INTO cmd ( USER, priv, cmd, sub_time, success ) VALUES ('egon','0755','ls -l /etc',NOW(),'yes'), ('egon','0755','cat /etc/passwd',NOW(),'no'), ('egon','0755','useradd xxx',NOW(),'no'), ('egon','0755','ps aux',NOW(),'yes'); # 查詢errlog表記錄 select * from errlog; # 刪除觸發器 drop trigger tri_after_insert_cmd;
開啓一個事務能夠包含一些SQL語句,這些SQL語句要麼同時成功要麼同時失敗,保證數據操做的安全性一致性,稱爲事務的原子性
保證了對數據操做的安全性
原子性:一個事務中包含的各類對數據的操做,要麼操做都成功,要麼都失敗
一致性:一致性和原子性是密切相關的,事務使數據庫從一個一致性的狀態變爲另外一個一致性狀態
隔離性:事務內的操做數據與另外一個事務內的操做數據是隔離的,互不干擾的
持久性(永久性):事務一旦提交就會發生永久性改變
# 修改數據以前先開啓事務操做 start transaction; # 修改操做 update user set balance=20000000 where name='Mr沈'; # 回滾到上一個狀態 rollback; # 開啓事務以後,只要沒有執行commit操做,數據其實都沒有真正刷新到硬盤 # 提交操做 commit; """開啓事務檢測操做是否完整,不完整主動回滾到上一個狀態,若是完整就應該執行commit操做"""
至關於自定義的函數:
內部封裝了一系列的SQL語句,讓不會mysql操做的的也能夠經過調用該存儲過程來操做數據庫,或者爲了方便調用
語法:
# 有參 delimiter$$ create procedure p1( in m int, # in表示這個參數必須只能是傳入不能被返回出去 in n int, out res int # out表示這個參數能夠被返回出去,還有一個inout表示便可以傳入也能夠被返回出去 ) begin select tname from teacher where tid > m and tid < n; set res=0; end$$ delimiter;
# 無參 delimiter $$ create procedure p1() begin select * from user; end $$ delimiter;
如何使用:
# 一、直接在mysql中調用 set @res=10 # res的值是用來判斷存儲過程是否被執行成功的依據,因此須要先定義一個變量@res存儲10 call p1(2,4,10); # 報錯 call p1(2,4,@res); # 查看結果 select @res; # 執行成功,@res變量值發生了變化 # 二、在python程序中調用 pymysql連接mysql 產生的遊表cursor.callproc('p1',(2,4,10)) # 內部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10; cursor.excute('select @_p1_2;')
注意與存儲過程的區別,mysql內置的函數只能SQL語句中使用
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'); select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');
# 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 ; END // delimiter ;
數據都是存在硬盤上,查詢數據就須要進行IO操做
索引在mysql中也叫鍵,是儲存引擎用於快速找到記錄的一種數據結構,相似於書的目錄
索引有三種:
注意:foreign key不是用來加速查詢用的,不在咱們研究範圍以內,上面三種key前兩種除了有加速查詢的效果以外還有額外的約束條件(primary key:非空且惟一,unique key:惟一),而index key沒有任何約束功能只會幫你加速查詢
本質都是:經過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,咱們能夠老是用同一種查找方式來鎖定數據。
b+樹
只有葉子結點存放真實數據,根和樹枝節點存的僅僅是虛擬數據
查詢次數由樹的層級決定,層級越低次數越少
一個磁盤塊兒的大小是必定的,那也就意味着能存的數據量是必定的。如何保證樹的層級最低呢?
彙集索引:指的就是表的主鍵,innodb引擎規定一張表中必需要有主鍵
輔助索引:查詢數據的時候不可能都是用id做爲篩選條件,也可能會用name,password等字段信息,那麼這個時候就沒法利用到彙集索引的加速查詢效果。就須要給其餘字段創建索引,這些索引就叫輔助索引
select name from user where name='Mr沈';
上述語句叫覆蓋索引:只在輔助索引的葉子節點中就已經找到了全部咱們想要的數據
select age from user where name='Mr沈';
上述語句叫非覆蓋索引,雖然查詢的時候命中了索引字段name,可是要查的是age字段,因此還須要利用主鍵纔去查找
若是name是索引的話,那麼直接用name=‘Mr沈’,這就是命中索引,若是不是直接用name,就是非命中索引