1.什麼是視圖:html
一個查詢語句的結果是一張虛擬表,將這種虛擬表保存下來他就變成了一個視圖。python
2.爲何要使用虛擬表:mysql
當頻繁須要用到多張表的連表結果,你就餓尅實現生成好視圖,以後直接調用便可,避免了反腐寫連表操做的sql語句。sql
3.如何使用:數據庫
語法: create view 視圖名 as 查詢語句; 例: create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id;
4.注意:數據結構
#1.視圖只有表結構,視圖中的數據仍是來源於原來的表ide
#2.不要改動視圖表中的數據函數
#3.通常狀況下不會頻繁的使用視圖來寫業務邏輯優化
1.什麼是觸發器:atom
當對某張表進行 增 刪 改操做的狀況下自動觸發的功能稱之爲觸發器。
2.爲何要是用是觸發器:
觸發器專門針對咱們對某一張表數據增insert、刪delete、改update的行爲,這類行爲一旦執行 就會觸發觸發器的執行,即自動運行另一段sql代碼
3.觸發器通常分爲六種狀況
增前 增後 刪前 刪後 改前 改後
4.語法使用
create trigger 觸發器的名字 after/before insert/update/delete on 表名 for each row begin sql語句 end # 刪除觸發器 drop trigger tri_after_insert_cmd; 細分: # 針對插入 create trigger tri_after_insert_t1 after insert on 表名 for each row begin sql代碼。。。 end create trigger tri_after_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_after_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_after_update_t2 before update on 表名 for each row begin sql代碼。。。 end 案例: 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 ; # 結束以後記得再改回來,否則後面結束符就都是$$了
1.什麼是事務:
一系列sql語句操做要麼同時成功,要麼同時失敗
2.事務的四大特性:
#1.原子性(atomicity:一組操做要麼都成功,要麼都失敗
#2.一致性(consistency):事務使數據庫從一個一致狀態轉變到另外一個一致狀態,一致性與原子性密切相關。即事務發生先後數據總額依然匹配。
#3.隔離性(isolation):各個事務之間的執行相互隔離互不干擾。
#4.持久性(durability):指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其餘操做或故障不該該對其有任何影響。只能經過「另開起一個事物」來抵消以前的錯誤
3.語法:
#表準備 create table user( id int primary key auto_increment, name char(32), balance int ); insert into user(name,balance) values ('wsb',1000), ('egon',1000), ('ysb',1000); 1.# 修改數據以前先開啓事務操做 start transaction; 2.# 一系列操做 例如 # 修改操做 update user set balance=900 where name='wsb'; #買支付100元 update user set balance=1010 where name='egon'; #中介拿走10元 update user set balance=1090 where name='ysb'; #賣家拿到90元 #3.# 回滾到上一個狀態即沒有第二步修改操做 rollback; 4.# 開啓事務以後,只要沒有執行commit操做,數據其實都沒有真正刷新到硬盤,(提交後再執行回滾,沒有任何回滾效果) commit; """開啓事務檢測操做是否完整,不完整主動回滾到上一個狀態,若是完整就應該執行commit操做""" # 站在python代碼的角度,應該實現的僞代碼邏輯, try: update user set balance=900 where name='wsb'; #買支付100元 update user set balance=1010 where name='egon'; #中介拿走10元 update user set balance=1090 where name='ysb'; #賣家拿到90元 except 異常: rollback; else: commit;
1.什麼是存儲過程:
存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,經過調用它的名字能夠執行其內部的一堆sql語句(相似於python中的自定義函數)
2.語法:
1.# 建立過程 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; # sql語句 set res=0; # 返回值 end $$ delimiter ; 2.# 如何使用 # 一、直接在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;') # 大前提:存儲過程在哪一個庫下面建立的只能在對應的庫下面才能使用!!!存儲
3.案例:
# 三、存儲過程與事務使用舉例(瞭解) delimiter // create PROCEDURE p5( OUT p_return_code tinyint ) BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR set p_return_code = 1; rollback; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING set p_return_code = 2; rollback; END; START TRANSACTION; update user set balance=900 where id =1; update user123 set balance=1010 where id = 2; update user set balance=1090 where id =3; COMMIT; -- SUCCESS set p_return_code = 0; #0表明執行成功 END // delimiter ;
1.注意:
注意與存儲過程的區別,mysql內置的函數只能在sql語句中使用!
2.參考博客:http://www.cnblogs.com/linhaifeng/articles/7495918.html#_label2
3.案例:
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) from blog group by date_format(sub_time,'%Y-%m');
1.什麼是索引:
在mysql中也叫鍵,是存儲引擎加速查找數據的一種數據結構。(索引就是一種數據結構,相似於書的目錄。意味着之後再查數據應該先找目錄再找數據,而不是用翻頁的方式查詢數據)
2.三種索引及區別:
#索引:
1.primary key 主鍵索引:加速查詢 ;不能重複;不能爲空
# 第一種: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '' # )engine=Innodb charset=utf8; # 第二種: alter table t1 change id id int auto_increment primary key;
2.unique key 惟一鍵索引:加快查詢;不能重複;unique(列名)
聯合惟一索引:加快查詢;不能重複;unique(列名,列名)
惟一索引: # 第一種: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '', # unique ix_name (name) # )engine=Innodb charset=utf8; # # 第二種: # create unique index 索引名稱(ix_name) on 表名(t1)(name); # create unique index 索引名稱(ix_name_age) on 表名(t1)(name,age);
3.index key 普通鍵索引:加快查詢
普通索引: # # 第一種: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '', # index ix_name (name) # )engine=Innodb charset=utf8; # # 第二種: # create index 索引名稱(ix_name) on 表名(t1)(name);
#區別:
注意foreign key不是用來加速查詢用的,不在咱們研究範圍以內,上面三種key前兩種除了有加速查詢的效果以外還有額外的約束條件(primary key:非空且惟一,unique key:惟一),而index key沒有任何約束功能只會幫你加速查詢。
drop index 索引名稱(ix_name) on 表名(t1);
版本5.3如下: # 刪除和修改的速度就變慢了 # # 版本5.5以上: # 刪除和修改的速度不是特別的慢
1.做用:查看sql語句是否使用了索引和執行效率
2.使用:explain sql語句 例:explain select * from where id=1\G
1.日誌文件:記錄了執行速度特別慢的sql語句
2.如何使用:
1. show variables like '%query%'; # # 2. set global long_query_time = 1; 設置慢查詢的時間 # 3. slow_query_log = ON # 4. slow_query_log_file = E:\program\mysql-5.6.44-winx64\data\oldboy-slow.log
show variables like '%general%'; # +------------------+------------------------------------------------+ # | Variable_name | Value | # +------------------+------------------------------------------------+ # | general_log | ON | # | general_log_file | E:\program\mysql-5.6.44-winx64\data\oldboy.log | # +------------------+------------------------------------------------+ # set global general_log = ON;
建立用戶 # create user '用戶名'@'IP地址' identified by '密碼'; # creaee user 'zekai'@'192.168.1.123' identified by '123qwe'; # creaee user 'zekai'@'192.168.1.%' identified by '123qwe'; # create user 'zekai'@'%' identified by '123qwe'; # # 刪除用戶 # drop user '用戶名'@'IP地址'; # 修改用戶 # rename user '用戶名'@'IP地址' to '新用戶名'@'IP地址'; # # 修改密碼 # set password for '用戶名'@'IP地址' = Password('新密碼') # # 受權: # grant 權限 on 數據庫.表 to '用戶'@'IP地址' -- 受權 # # grant select on db1.* to 'zekai'@'%'; # grant select on *.* to 'zekai'@'%'; # grant select, insert, delete on db1.* to 'zekai'@'%'; # # 記住: # flush privileges;
3.b+樹
#1.注意:
只有葉子結點存放真實數據,根和樹枝節點存的僅僅是虛擬數據
查詢次數由樹的層級決定,層級越低次數越少一個磁盤塊兒的大小是必定的,那也就意味着能存的數據量是必定的。如何保證樹的層級最低呢?一個磁盤塊兒存放佔用空間比較小的數據項,思考咱們應該給咱們一張表裏面的什麼字段字段創建索引可以下降樹的層級高度>>> 主鍵id字段。
彙集索引(primary key)
#1.彙集索引其實指的就是表的主鍵,innodb引擎規定一張表中必需要有主鍵。
特色:葉子結點放的一條條完整的記錄
#1.輔助索引:
查詢數據的時候不可能都是用id做爲篩選條件,也可能會用name,password等字段信息,那麼這個時候就沒法利用到彙集索引的加速查詢效果。就須要給其餘字段創建索引,這些索引就叫輔助索引
特色:葉子結點存放的是輔助索引字段對應的那條記錄的主鍵的值(好比:按照name字段建立索引,那麼葉子節點存放的是:{name對應的值:name所在的那條記錄的主鍵值})
#2.輔助索引分類:
select name from user where name='jason';
上述語句叫覆蓋索引:只在輔助索引的葉子節點中就已經找到了全部咱們想要的數據
select age from user where name='jason';
上述語句叫非覆蓋索引,雖然查詢的時候命中了索引字段name,可是要查的是age字段,因此還須要利用主鍵纔去查找