使用select…for update會(huì)把數(shù)據(jù)給鎖住,不過我們需要注意一些鎖的級(jí)別,MySQL InnoDB默認(rèn)行級(jí)鎖。行級(jí)鎖都是基于索引的,如果一條SQL語句用不到索引是不會(huì)使用行級(jí)鎖的,會(huì)使用表級(jí)鎖把整張表鎖住。
索引類型
普通索引:MySQL中基本索引類型,沒有什么限制,允許在定義索引的列中插入重復(fù)值和空值,純粹為了查詢數(shù)據(jù)更快一點(diǎn)
唯一索引:索引列中的值必須是唯一的,但是允許為空值
主鍵索引:是一種特殊的唯一索引,不允許有空值。(主鍵約束,就是一個(gè)主鍵索引)
組合索引:在表中的多個(gè)字段組合上創(chuàng)建的索引,只有在查詢條件中使用了這些字段的左邊字段時(shí),索引才會(huì)被使用,使用組合索引時(shí)遵循最左前綴集合。例如,這里由id、name和age3個(gè)字段構(gòu)成的索引,索引行中就按id/name/age的順序存放,索引可以索引下面字段組合(id,name,age)、(id,name)或者(id)。如果要查詢的字段不構(gòu)成索引最左面的前綴,那么就不會(huì)是用索引,比如,age或者(name,age)組合就不會(huì)使用索引查詢
全文索引:全文索引,只有在MyISAM引擎上才能使用。在一堆文字中,通過其中的某個(gè)關(guān)鍵字等,就能找到該字段所屬的記錄行
聚集索引與非聚集索引
聚集索引:鍵值的邏輯順序決定了表中相應(yīng)行的物理順序。由于聚集索引規(guī)定數(shù)據(jù)在表中的物理存儲(chǔ)順序,因此一個(gè)表只能包含一個(gè)聚集索引。但該索引可以包含多個(gè)列(組合索引)。當(dāng)索引值唯一時(shí),使用聚集索引查找特定的行也很有效率。例如,使用唯一雇員 ID 列 emp_id 查找特定雇員的最快速的方法,是在 emp_id 列上創(chuàng)建聚集索引或 PRIMARY KEY 約束。
非聚集索引:索引的邏輯順序與磁盤上行的物理存儲(chǔ)順序不同。
索引的葉節(jié)點(diǎn)就是數(shù)據(jù)節(jié)點(diǎn)。而非聚簇索引的葉節(jié)點(diǎn)仍然是索引節(jié)點(diǎn),只不過有一個(gè)指針指向?qū)?yīng)的數(shù)據(jù)塊

使用索引的注意事項(xiàng)
1.非空字段:在mysql中,含有空值的列很難進(jìn)行查詢優(yōu)化,因?yàn)樗鼈兪沟盟饕?、索引的統(tǒng)計(jì)信息以及比較運(yùn)算更加復(fù)雜
2.使用短索引:對(duì)串列進(jìn)行索引,如果可以就應(yīng)該指定一個(gè)前綴長度。例如,如果有一個(gè)char(255)的列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是唯一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作。
3.索引列排序:mysql查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫默認(rèn)排序可以符合要求的情況下不要使用排序操作,盡量不要包含多個(gè)列的排序,如果需要最好給這些列建復(fù)合索引。
4.like語句操作: 一般情況下不鼓勵(lì)使用like操作,如果非使用不可,注意正確的使用方式。like ‘%aaa%’不會(huì)使用索引,而like ‘a(chǎn)aa%’可以使用索引。
5.不要在列上進(jìn)行運(yùn)算
6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的
7.索引要建立在經(jīng)常進(jìn)行select操作的字段上。
8.索引要建立在值比較唯一的字段上。
9.對(duì)于那些定義為text、image和bit數(shù)據(jù)類型的列不應(yīng)該增加索引。因?yàn)檫@些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少。
10.在where和join中出現(xiàn)的列需要建立索引。
11.where的查詢條件里有不等號(hào)(where column != …),mysql將無法使用索引
12.如果where字句的查詢條件里使用了函數(shù)(如:where DAY(column)=…),mysql將無法使用索引。
13.在join操作中(需要從多個(gè)數(shù)據(jù)表提取數(shù)據(jù)時(shí)),mysql只有在主鍵和外鍵的數(shù)據(jù)類型相同時(shí)才能使用索引,否則及時(shí)建立了索引也不會(huì)使用。
觸發(fā)器作用
觸發(fā)器是一種特殊的存儲(chǔ)過程,主要是通過事件來觸發(fā)而被執(zhí)行的。它可以強(qiáng)化約束,來維護(hù)數(shù)據(jù)的完整性和一致性,可以跟蹤數(shù)據(jù)庫內(nèi)的操作從而不允許未經(jīng)許可的更新和變化
存儲(chǔ)過程
存儲(chǔ)過程是一個(gè)預(yù)編譯的SQL語句,優(yōu)點(diǎn)是允許模塊化的設(shè)計(jì),就是說只需創(chuàng)建一次,以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL,使用存儲(chǔ)過程比單純SQL語句執(zhí)行要快
優(yōu)點(diǎn):1)存儲(chǔ)過程是預(yù)編譯過的,執(zhí)行效率高。
2)存儲(chǔ)過程的代碼直接存放于數(shù)據(jù)庫中,通過存儲(chǔ)過程名直接調(diào)用,減少網(wǎng)絡(luò)通訊。
3)安全性高,執(zhí)行存儲(chǔ)過程需要有一定權(quán)限的用戶。
4)存儲(chǔ)過程可以重復(fù)使用,可以通過編程語言調(diào)用。
缺點(diǎn):每個(gè)數(shù)據(jù)庫的存儲(chǔ)過程語法幾乎都不一樣,十分難以維護(hù)(不通用)
業(yè)務(wù)邏輯放在數(shù)據(jù)庫上,難以迭代。
數(shù)據(jù)庫鎖
共享鎖:又稱讀鎖,是讀取操作創(chuàng)建的鎖。其他用戶可以并發(fā)讀取數(shù)據(jù),但任何事務(wù)都不能對(duì)數(shù)據(jù)進(jìn)行修改。如果事務(wù)T對(duì)數(shù)據(jù)A加上共享鎖后,則其他事務(wù)只能對(duì)A再加共享鎖,不能加排他鎖。獲準(zhǔn)共享鎖的事務(wù)只能讀數(shù)據(jù),不能修改數(shù)據(jù)。SELECT ... LOCK IN SHARE MODE;
獨(dú)占鎖:又稱寫鎖、排他鎖,如果事務(wù)T對(duì)數(shù)據(jù)A加上排他鎖后,則其他事務(wù)不能再對(duì)A加任何類型的鎖。獲準(zhǔn)排他鎖的事務(wù)既能讀數(shù)據(jù),又能修改數(shù)據(jù)。SELECT ... FOR UPDATE;
四大隔離級(jí)別
1)Read Uncommitted(讀未提交):一個(gè)事務(wù)在執(zhí)行過程中,既可以訪問其他事務(wù)未提交的新插入的數(shù)據(jù),又可以訪問未提交的修改數(shù)據(jù)。如果一個(gè)事務(wù)已經(jīng)開始寫數(shù)據(jù),則另外一個(gè)事務(wù)不允許同時(shí)進(jìn)行寫操作,但允許其他事務(wù)讀此行數(shù)據(jù)。此隔離級(jí)別可防止丟失更新。
實(shí)現(xiàn)方式:讀數(shù)據(jù)時(shí)候不加鎖,寫數(shù)據(jù)瞬間(發(fā)生更新的瞬間)加行級(jí)別的共享鎖,提交時(shí)釋放鎖。行級(jí)別的共享鎖,不會(huì)對(duì)讀產(chǎn)生影響,但是可以防止兩個(gè)同時(shí)的寫操作
2)Read Committed(讀已提交):一個(gè)事務(wù)在執(zhí)行過程中,既可以訪問其他事務(wù)成功提交的新插入的數(shù)據(jù),又可以訪問成功修改的數(shù)據(jù)。讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問該行數(shù)據(jù),但是未提交的寫事務(wù)將會(huì)禁止其他事務(wù)訪問該行。此隔離級(jí)別可有效防止臟讀
實(shí)現(xiàn)方式:事務(wù)讀取數(shù)據(jù)(讀到數(shù)據(jù)的時(shí)候)加行級(jí)共享鎖,讀完釋放;事務(wù)寫數(shù)據(jù)時(shí)候(寫操作發(fā)生的瞬間)加行級(jí)獨(dú)占鎖,事務(wù)結(jié)束釋放。由于事務(wù)寫操作加上獨(dú)占鎖,因此事務(wù)寫操作時(shí),讀操作也不能進(jìn)行,因此,不能讀到事務(wù)的未提交數(shù)據(jù),避免了臟讀的問題。但是由于,讀操作的鎖加在讀上面,而不是加在事務(wù)之上,所以,在同一事務(wù)的兩次讀操作之間可以插入其他事務(wù)的寫操作,所以可能發(fā)生不可重復(fù)讀的問題。
3)Repeatable Read(可重復(fù)讀?。阂粋€(gè)事務(wù)在執(zhí)行過程中,可以訪問其他事務(wù)成功提交的新插入的數(shù)據(jù),但不可以訪問成功修改的數(shù)據(jù)。讀取數(shù)據(jù)的事務(wù)將會(huì)禁止寫事務(wù)(但允許讀事務(wù)),寫事務(wù)則禁止任何其他事務(wù)。此隔離級(jí)別可有效防止不可重復(fù)讀和臟讀。
實(shí)現(xiàn)方式:事務(wù)讀取數(shù)據(jù)在讀操作開始的瞬間就加上行級(jí)共享鎖,而且在事務(wù)結(jié)束的時(shí)候才釋放。分析方法和讀提交數(shù)據(jù)類似。但是,由于加鎖只是加在行上,所以,仍然可能發(fā)生虛讀的問題。
4)Serializable(可串行化):提供嚴(yán)格的事務(wù)隔離。它要求事務(wù)序列化執(zhí)行,事務(wù)只能一個(gè)接著一個(gè)地執(zhí)行,不能并發(fā)執(zhí)行。此隔離級(jí)別可有效防止臟讀、不可重復(fù)讀和幻讀。但這個(gè)級(jí)別可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競爭,在實(shí)際應(yīng)用中很少使用。