什么是事務(wù)
數(shù)據(jù)庫的事務(wù)(Transaction)是一種機(jī)制、一個(gè)操作序列,包含了一組數(shù)據(jù)庫操作命令。事務(wù)把所有的命令作為一個(gè)整體一起向系統(tǒng)
提交或撤銷操作請求,即這一組數(shù)據(jù)庫命令要么都執(zhí)行,要么都不執(zhí)行,因此事務(wù)是一個(gè)不可分割的工作邏輯單元。
在數(shù)據(jù)庫系統(tǒng)上執(zhí)行并發(fā)操作時(shí),事務(wù)是作為最小的控制單元來使用的,特別適用于多用戶同時(shí)操作的數(shù)據(jù)庫系統(tǒng)。例如,航空公司的訂票系統(tǒng)、銀行、保險(xiǎn)公司以及證券交易系統(tǒng)等。
事務(wù)的特性(ACID)
① 原子性:事務(wù)是最小的執(zhí)行單位,不允許分割。事務(wù)的原子性確保動作要么全部完成,要么完全不起作用;
例如轉(zhuǎn)賬的這兩個(gè)關(guān)鍵操作(將張三的余額減少200元,將李四的余額增加200元)。要么全部完成,要么全部失敗。
② 一致性: 確保從一個(gè)正確的狀態(tài)轉(zhuǎn)換到另外一個(gè)正確的狀態(tài),這就是一致性。例如轉(zhuǎn)賬業(yè)務(wù)中,將張三的余額減少200元,中間發(fā)生斷電情況,
李四的余額沒有增加200元,這個(gè)就是不正確的狀態(tài),違反一致性。又比如表更新事務(wù),一部分?jǐn)?shù)據(jù)更新了,但一部分?jǐn)?shù)據(jù)沒有更新,這也是違反一致性的;
③ 隔離性:并發(fā)訪問數(shù)據(jù)庫時(shí),一個(gè)用戶的事務(wù)不被其他事務(wù)所干擾,各并發(fā)事務(wù)之間數(shù)據(jù)庫是獨(dú)立的;
④ 持久性:一個(gè)事務(wù)被提交之后,對數(shù)據(jù)庫中數(shù)據(jù)的改變是持久的,即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響。
數(shù)據(jù)庫隔離級別及原理
Read Uncommitted(讀未提交)
Read Committed(讀已提交)
Repeatable Read(可重復(fù)讀)
Serializable(可序列化)
鎖類型簡述
共享鎖(S鎖):假設(shè)事務(wù)T1對數(shù)據(jù)A加上共享鎖,那么事務(wù)T2可以讀數(shù)據(jù)A,不能修改數(shù)據(jù)A。
排他鎖(X鎖):假設(shè)事務(wù)T1對數(shù)據(jù)A加上排他鎖,那么事務(wù)T2不能讀數(shù)據(jù)A,不能修改數(shù)據(jù)A。
各個(gè)隔離級別鎖應(yīng)用
讀未提交
Read Uncommitted:最低隔離級別,什么都不要做,一個(gè)事務(wù)可以讀到另一個(gè)事務(wù)未提交的結(jié)果。所有的并發(fā)事務(wù)問題都會發(fā)生。
原理:
事務(wù)對當(dāng)前讀取的數(shù)據(jù)不加鎖;
事務(wù)對數(shù)據(jù)更新前添加 行級共享鎖,直到事務(wù)結(jié)束才釋放。
可能發(fā)生的情況:
事務(wù)1讀取某些數(shù)據(jù)記錄時(shí),事務(wù)2也能對這些記錄進(jìn)行讀取、更新;當(dāng)事務(wù)2對這些記錄進(jìn)行更新時(shí),事務(wù)1再次讀取記錄,能讀到事務(wù)2對該記錄的修改版本,即使更新尚未提交。
事務(wù)1更新某些數(shù)據(jù)記錄時(shí),事務(wù)2不能對這行記錄做更新,直到事務(wù)1結(jié)束。
簡單地理解就是:
允許事務(wù)同時(shí)讀數(shù)據(jù)
允許一個(gè)事務(wù)讀取數(shù)據(jù)同時(shí)另外一個(gè)事務(wù)修改數(shù)據(jù)
必須等更新數(shù)據(jù)的事務(wù)執(zhí)行完成后,才能對執(zhí)行其他的讀取或者修改該數(shù)據(jù)的事務(wù)
讀已提交
Read Committed:只有在事務(wù)提交后,其更新結(jié)果才會被其他事務(wù)看見??梢越鉀Q臟讀問題。
原理:
事務(wù)對當(dāng)前被讀取的數(shù)據(jù)加 行級共享鎖(當(dāng)讀到時(shí)才加鎖),一旦讀完該行,立即釋放該行級共享鎖;
事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加 行級排他鎖,直到事務(wù)結(jié)束才釋放。
可能發(fā)生的情況:
事務(wù)1讀取某行記錄時(shí),事務(wù)2也能對這行記錄進(jìn)行讀取、更新;當(dāng)事務(wù)2對該記錄進(jìn)行更新時(shí),事務(wù)1再次讀取該記錄,讀到的只能是事務(wù)2對其更新前的版本,要不就是事務(wù)2提交后的版本。
事務(wù)1更新某行記錄時(shí),事務(wù)2不能對這行記錄做更新,直到事務(wù)1結(jié)束。
簡單地理解就是:
允許事務(wù)同時(shí)讀數(shù)據(jù)
必須一個(gè)事務(wù)讀取完數(shù)據(jù)后,另外一個(gè)事務(wù)才能修改該數(shù)據(jù)
必須等更新數(shù)據(jù)的事務(wù)執(zhí)行完成后,才能對執(zhí)行其他的讀取或者修改該數(shù)據(jù)的事務(wù)
可重復(fù)讀
Repeated Read:在一個(gè)事務(wù)中,對于同一份數(shù)據(jù)的讀取結(jié)果總是相同的,無論是否有其他事務(wù)對這份數(shù)據(jù)進(jìn)行操作,以及這個(gè)事務(wù)是否提交。可以解決臟讀、不可重復(fù)讀。
原理:
事務(wù)在讀取某數(shù)據(jù)的瞬間(就是開始讀取的瞬間),必須先對其加 行級共享鎖,直到事務(wù)結(jié)束才釋放;
事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加 行級排他鎖,直到事務(wù)結(jié)束才釋放。
可能發(fā)生的情況:
事務(wù)1讀取某行記錄時(shí),事務(wù)2也能對這行記錄進(jìn)行讀取、更新;當(dāng)事務(wù)2對該記錄進(jìn)行更新時(shí),事務(wù)1再次讀取該記錄,讀到的仍然是第一次讀取的那個(gè)版本。
事務(wù)1更新某行記錄時(shí),事務(wù)2不能對這行記錄做更新,直到事務(wù)1結(jié)束。
簡單地理解就是:
允許事務(wù)同時(shí)讀數(shù)據(jù)
必須等讀取數(shù)據(jù)的事務(wù)執(zhí)行完成后,才能對執(zhí)行其他的修改該數(shù)據(jù)的事務(wù)
必須等更新數(shù)據(jù)的事務(wù)執(zhí)行完成后,才能對執(zhí)行其他的讀取或者修改該數(shù)據(jù)的事務(wù)
可序列化
Serialization:事務(wù)串行化執(zhí)行,隔離級別最高,犧牲了系統(tǒng)的并發(fā)性??梢越鉀Q并發(fā)事務(wù)的所有問題。
事務(wù)在讀取某數(shù)據(jù)的瞬間(就是開始讀取的瞬間),必須先對其加 行級共享鎖,直到事務(wù)結(jié)束才釋放;
事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加 行級排他鎖,直到事務(wù)結(jié)束才釋放。
可能發(fā)生的情況:
事務(wù)1讀取某行記錄時(shí),事務(wù)2也能對這行記錄進(jìn)行讀取、更新;當(dāng)事務(wù)2對該記錄進(jìn)行更新時(shí),事務(wù)1再次讀取該記錄,讀到的仍然是第一次讀取的那個(gè)版本。
事務(wù)1更新某行記錄時(shí),事務(wù)2不能對這行記錄做更新,直到事務(wù)1結(jié)束。
簡單地理解就是:
所有的事務(wù)必須等上一個(gè)事務(wù)執(zhí)行完成后才開始執(zhí)行
MySQL 存儲引擎 MyISAM 與 InnoDB 兩種存儲引擎的區(qū)別
一、InnoDB支持事務(wù),MyISAM不支持,這一點(diǎn)是非常之重要。事務(wù)是一種高級的處理方式,如在一些列增刪改中只要哪個(gè)出錯(cuò)還可以回滾還原,而MyISAM就不可以了。
二、MyISAM適合查詢以及插入為主的應(yīng)用,InnoDB適合頻繁修改以及涉及到安全性較高的應(yīng)用
三、InnoDB支持外鍵,MyISAM不支持
四、MySQL 在 5.1 之前版本默認(rèn)存儲引擎是 MyISAM,5.1 之后版本默認(rèn)存儲引擎是 InnoDB
五、InnoDB不支持FULLTEXT類型的索引
六、InnoDB中不保存表的行數(shù),如select count(*) from table時(shí),InnoDB需要掃描一遍整個(gè)表來計(jì)算有多少行,但是MyISAM只要簡
單的讀出保存好的行數(shù)即可。注意的是,當(dāng)count(*)語句包含where條件時(shí)MyISAM也需要掃描整個(gè)表
七、對于自增長的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯(lián)合索引
八、清空整個(gè)表時(shí),InnoDB是一行一行的刪除,效率非常慢。MyISAM則會重建表
九、InnoDB支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like ‘%lee%’
通過以上九點(diǎn)區(qū)別,結(jié)合個(gè)人博客的特點(diǎn),推薦個(gè)人博客系統(tǒng)使用MyISAM,因?yàn)樵诓┛屠镏饕僮魇亲x取和寫入,很少有鏈?zhǔn)讲?/p>
作。所以選擇MyISAM引擎使你博客打開頁面的效率要高于InnoDB引擎的博客,當(dāng)然只是個(gè)人的建議,大多數(shù)博客還是根據(jù)實(shí)際情
況下謹(jǐn)慎選擇。
一些關(guān)于MyISAM與InnoDB選擇使用:
MYISAM和INNODB是Mysql數(shù)據(jù)庫提供的兩種存儲引擎。兩者的優(yōu)劣可謂是各有千秋。INNODB會支持一些關(guān)系數(shù)據(jù)庫的高級功
能,如事務(wù)功能和行級鎖,MYISAM不支持。MYISAM的性能更優(yōu),占用的存儲空間少。所以,選擇何種存儲引擎,視具體應(yīng)用而
定。
如果你的應(yīng)用程序一定要使用事務(wù),毫無疑問你要選擇INNODB引擎。但要注意,INNODB的行級鎖是有條件的。在where條件沒有使用主鍵時(shí),照樣會鎖全表。
比如DELETE FROM mytable這樣的刪除語句。如果你的應(yīng)用程序?qū)Σ樵冃阅芤筝^高,就要使用MYISAM了。MYISAM索引和數(shù)據(jù)是分開的,而且其索引是壓縮的,可以更好地利用內(nèi)存。
所以它的查詢性能明顯優(yōu)于INNODB。
壓縮后的索引也能節(jié)約一些磁盤空間。MYISAM擁有全文索引的功能,這可以極大地優(yōu)化LIKE查詢的效率。
有人說MYISAM只能用于小型應(yīng)用,其實(shí)這只是一種偏見。如果數(shù)據(jù)量比較大,這是需要通過升級架構(gòu)來解決,比如分表分庫,而不是單純地依賴存儲引擎。
關(guān)于Mysql數(shù)據(jù)庫默認(rèn)的存儲引擎:
MyISAM和InnoDB是MySQL的兩種存儲引擎。
如果是默認(rèn)安裝,那就應(yīng)該是InnoDB,你可以在my.ini文件中找到default-storage-engine=INNODB;當(dāng)然你可以在建表時(shí)指定相應(yīng)的存儲引擎。
通過show create table xx 可以看見相應(yīng)信息。
Mysql中InnoDB和MyISAM的比較
MyISAM:
每個(gè)MyISAM在磁盤上存儲成三個(gè)文件。第一個(gè)文件的名字以表的名字開始,擴(kuò)展名指出文件類型。.frm文件存儲表定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。
MyISAM表格可以被壓縮,而且它們支持全文搜索。不支持事務(wù),而且也不支持外鍵。如果事物回滾將造成不完全回滾,不具有原子
性。在進(jìn)行update時(shí)進(jìn)行表鎖,并發(fā)量相對較小。如果執(zhí)行大量的SELECT,MyISAM是更好的選擇。
MyISAM的索引和數(shù)據(jù)是分開的,并且索引是有壓縮的,內(nèi)存使用率就對應(yīng)提高了不少。能加載更多索引,而Innodb是索引和數(shù)據(jù)是
緊密捆綁的,沒有使用壓縮從而會造成Innodb比MyISAM體積龐大不小
MyISAM緩存在內(nèi)存的是索引,不是數(shù)據(jù)。而InnoDB緩存在內(nèi)存的是數(shù)據(jù),相對來說,服務(wù)器內(nèi)存越大,InnoDB發(fā)揮的優(yōu)勢越大。
優(yōu)點(diǎn):查詢數(shù)據(jù)相對較快,適合大量的select,可以全文索引。
缺點(diǎn):不支持事務(wù),不支持外鍵,并發(fā)量較小,不適合大量update
InnoDB:
這種類型是事務(wù)安全的。.它與BDB類型具有相同的特性,它們還支持外鍵。InnoDB表格速度很快。具有比BDB還豐富的特性,因此如果
需要一個(gè)事務(wù)安全的存儲引擎,建議使用它。在update時(shí)表進(jìn)行行鎖,并發(fā)量相對較大。
如果你的數(shù)據(jù)執(zhí)行大量的INSERT或UPDATE,出于性能方面的考慮,應(yīng)該使用InnoDB表。
優(yōu)點(diǎn):支持事務(wù),支持外鍵,并發(fā)量較大,適合大量update
缺點(diǎn):查詢數(shù)據(jù)相對較快,不適合大量的select
對于支持事物的InnoDB類型的表,影響速度的主要原因是AUTOCOMMIT默認(rèn)設(shè)置是打開的,而且程序沒有顯式調(diào)用BEGIN 開始事
務(wù),導(dǎo)致每插入一條都自動Commit,嚴(yán)重影響了速度。可以在執(zhí)行sql前調(diào)用begin,多條sql形成一個(gè)事物(即使autocommit打開也可以),將大大提高性能。
基本的差別為:MyISAM類型不支持事務(wù)處理等高級處理,而InnoDB類型支持。
MyISAM類型的表強(qiáng)調(diào)的是性能,其執(zhí)行數(shù)度比InnoDB類型更快,但是不提供事務(wù)支持,而InnoDB提供事務(wù)支持以及外部鍵等高級數(shù)據(jù)庫功能。
innodb和myisam更新比較:
innodb的數(shù)據(jù)組織就是按照主鍵建成的一個(gè)B+樹,如果沒有顯示的定義主鍵,那么innodb會選一個(gè)not null unique key,作為主鍵,如果還是沒有,
那么innodb會創(chuàng)建一個(gè) 6字節(jié)的主鍵,主鍵索引到
頁不是具體行位置。不是遞增的主鍵會使得插入的速度很慢,例如使用手機(jī)號或身份證號做為主鍵,所以善用AUTO_INCREMENT。
插入的速度和查詢的速度有時(shí)候是不可調(diào)和的矛盾
說InnoDB不適合做count是不對的,MyISAM也是一樣的慢,只不過MyISAM將正表的行數(shù)緩存起來,所以count整表很快,如果有查
詢條件,并且不是主鍵查詢,那就沒有什么區(qū)別,主鍵count慢的原因是innodb是按照主鍵組織的,按照主鍵count的時(shí)候,會加載數(shù)據(jù)
InnoDB的頁式存儲會使得InnoDB更容易做整表緩存和熱備份,如果表索引很多,那么InnoDB的更新速度要大于MyISAM,因?yàn)镮nnoDB的輔助索引關(guān)聯(lián)的是表的主鍵,
是一個(gè)邏輯的值,而MyISAM的所有索引關(guān)聯(lián)的是數(shù)據(jù)的物理位置,更新時(shí)有可能數(shù)據(jù)的物理位置發(fā)生變化,如果發(fā)生變化,那么所有的索引都要做更新
InnoDB 中不保存表的具體行數(shù),也就是說,執(zhí)行select count(*) from table時(shí),InnoDB要掃描一遍整個(gè)表來計(jì)算有多少行,但是MyI
SAM只要簡單的讀出保存好的行數(shù)即可。注意的是,當(dāng)count(*)語句包含 where條件時(shí),兩種表的操作是一樣的。