做者:檸檬橙1024
原文:https://blog.csdn.net/u011644231/article/details/105094134程序員
學習關係型數據庫MySQL是很好的切入點,大部分人工做中用慣了CRUD,對面試官刨根問底的靈魂拷問你還能對答如流嗎?咱們有必要了解一些更深層次的數據庫基礎原理。
整理了面試中,關於MySQL事務和存儲引擎10個FAQ(Frequently asked questions),你想知道的都在這裏。
什麼是事務?
事務就是「一組原子性的SQL查詢」,或者說一個獨立的工做單元。若是數據庫引擎可以成功地對數據庫應用該組查詢的所有語句,那麼就執行該組查詢。若是其中有任何一條語句由於崩潰或其餘緣由沒法執行,那麼全部的語句都不會執行。也就是說,事務內的語句,要麼所有執行成功,要麼所有執行失敗。
事務控制語法知道嗎?
BEGIN 或 START TRANSACTION 顯式地開啓一個事務;
COMMIT / COMMIT WORK兩者是等價的。提交事務,並使已對數據庫進行的全部修改爲爲永久性的;
ROLLBACK / ROLLBACK WORK。回滾會結束用戶的事務,並撤銷正在進行的全部未提交的修改;
SAVEPOINT identifier 在事務中建立一個保存點,一個事務中能夠有多個 SAVEPOINT;
RELEASE SAVEPOINT identifier 刪除一個事務的保存點;
ROLLBACK TO identifier 把事務回滾到標記點;
SET TRANSACTION 用來設置事務的隔離級別。InnoDB 存儲引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE複製代碼
用通俗的語言說說你理解的事務
用銀行業務舉個栗子,用戶lemon有兩銀行卡,一張是招商銀行CMBC的工資卡,另外一張是工商銀行ICBC的儲蓄卡,每個月5號發工資都要把招行卡的100萬轉到建設銀行儲蓄卡帳戶。記住這裏的銀行縮寫後面就是對應的數據表名稱,你要記不住,我給你理一理。
招商銀行(CMBC):「存麼?白癡!」
中國工商銀行(ICBC): 「愛存不存!」
中國建設銀行(CCB): 「存?存不?」
中國銀行(BC): 「不存!」
中國農業銀行(ABC): 「啊,不存!」
民生銀行(CMSB):「存麼?SB!" 興業銀行(CIB):「存一百。」 國家開發銀行(CDB):「存點吧!」 匯豐銀行(HSBC):「仍是不存!」複製代碼
這個轉帳的操做能夠簡化抽成一個事務,包含以下步驟:
這個轉帳的操做能夠簡化抽成一個事務,包含以下步驟:
-
查詢CMBC帳戶的餘額是否大於100萬
-
從CMBC帳戶餘額中減去100萬
-
在ICBC帳戶餘額中增長100萬
START TRANSACTION;
SELECT balance FROM CMBC WHERE username='lemon';
UPDATE CMBC SET balance = balance - 1000000.00 WHERE username = 'lemon';
UPDATE ICBC SET balance = balance + 1000000.00 WHERE username = 'lemon';
COMMIT;複製代碼
事務的ACID特性是什麼?
ACID實際上是事務特性的英文首字母縮寫,具體的含義是這樣的:
一個事務必須被視爲一個不可分割的最小工做單元,整個事務中的全部操做要麼所有提交成功,要麼所有失敗回滾,對於一個事務來講,不可能只執行其中的一部分操做。
數據庫老是從一個一致性的狀態轉換到另一個一致性的狀態。在前面的例子中,一致性確保了,即便在執行第3、四條語句之間時系統崩潰,CMBC帳戶中也不會損失100萬,否則lemon要哭死由於事務最終沒有提交,因此事務中所作的修改也不會保存到數據庫中。
一般來講,一個事務所作的修改在最終提交之前,對其餘事務是不可見的。在前面的例子中,當執行完第三條語句、第四條語句還未開始時,此時若是有其餘人也準備給lemon的CMBC帳戶存錢,那他看到的CMBC帳戶裏仍是有100萬的。
一旦事務提交,則其所作的修改就會永久保存到數據庫中。此時即便系統崩潰,修改的數據也不會丟失。持久性是個有點模糊的概念,由於實際上持久性也分不少不一樣的級別。有些持久性策略可以提供很是強的安全保障,而有些則未必。並且「不可能有能作到100%的持久性保證的策略」不然還須要備份作什麼。
什麼是髒讀、不可重複讀、幻讀?
在事務A修改數據以後提交數據以前,這時另外一個事務B來讀取數據,若是不加控制,事務B讀取到A修改過數據,以後A又對數據作了修改再提交,則B讀到的數據是髒數據,此過程稱爲髒讀Dirty Read。
一個事務內在讀取某些數據後的某個時間,再次讀取之前讀過的數據,卻發現其讀出的數據已經發生了變動、或者某些記錄已經被刪除了。
事務A在按查詢條件讀取某個範圍的記錄時,事務B又在該範圍內插入了新的知足條件的記錄,當事務A再次按條件查詢記錄時,會產生新的知足條件的記錄(幻行 Phantom Row)
不可重複讀與幻讀有什麼區別?
1.不可重複讀的重點是修改:在同一事務中,一樣的條件,第一次讀的數據和第二次讀的「數據不同」。(由於中間有其餘事務提交了修改)
2.幻讀的重點在於新增或者刪除:在同一事務中,一樣的條件,第一次和第二次讀出來的「記錄數不同」。(由於中間有其餘事務提交了插入/刪除)
SQL的四個隔離級別知道嗎?具體是什麼解決了什麼問題說說看
SQL實現了四個標準的隔離級別,每一種級別都規定了一個事務中所作的修改,哪些在事務內和事務間是可見的,哪些是不可見的。低級別的隔離級通常支持更高的併發處理,並擁有更低的系統開銷。
各個隔離級別能夠不一樣程度的解決髒讀、不可重複讀、幻讀。隔離級別各有所長,沒有完美的解決方案,脫離業務場景談具體實施都是耍流氓。
MySQL中哪些存儲引擎支持事務?
MySQL中InnoDB和NDB Cluster存儲引擎提供了事務處理能力,以及其餘支持事務的第三引擎。
什麼是自動提交?
MySQL默認採用自動提交AUTOCOMMIT模式。也就是說,若是不是顯式地開始一個事務,則每一個查詢都被看成一個事務執行提交操做。
對於MyISAM或者內存表這些事務型的表,修改AUTOCOMMIT不會有任何影響。對這類表來講,沒有COMMIT或者ROLLBACK的概念,也能夠說是至關於一直處於AUTOCOMMIT啓用的模式。
在事務中能夠混合使用存儲引擎嗎?
儘可能不要再同一個事務中使用多種存儲引擎,MySQL服務器層無論理事務,事務是由下層的存儲引擎實現的。
若是在事務中混合使用了事務型和非事務型的表(例如InnoDB和MyISAM表),在正常提交的狀況下不會有什麼問題。
但若是該事務須要回滾,非事務型的表上的變動就沒法撤銷,這會致使數據庫處於不一致的狀態,這種狀況很難修復,事務的最終結果將沒法肯定。因此,爲每張表選擇合適的存儲引擎很是重要。
MySQL存儲引擎類型有哪些?
最經常使用的存儲引擎是InnoDB引擎和MyISAM存儲引擎,InnoDB是MySQL的默認事務引擎。
show table status from 'your_db_name' where name='your_table_name';
查詢結果表中的`Engine`字段指示存儲引擎類型。複製代碼
InnoDB存儲引擎的特色和應用場景?
InnoDB是MySQL的默認「事務引擎」,被設置用來處理大量短時間(short-lived)事務,短時間事務大部分狀況是正常提交的,不多會回滾。
更多InnoDB事務模型相關,參考MySQL官方手冊。
歷史
現代MySQL版本中的InnoDB在歷史上叫InnoDB plugin,這個MySQL插件在2008年被開發出來,直到2010在Oracle收購了Sun公司後,發佈的MySQL5.5才正式使用InnoDB plugin替代了舊版本的InnoDB,至此 「備胎」成功轉正成爲MySQL的御用引擎而再也不是插件,你看一個插件都這麼努力。
特色
採用多版本併發控制(MVCC,MultiVersion Concurrency Control)來支持高併發。而且實現了四個標準的隔離級別,經過間隙鎖next-key locking策略防止幻讀的出現。
引擎的表基於聚簇索引創建,聚簇索引對主鍵查詢有很高的性能。不過它的二級索引secondary index非主鍵索引中必須包含主鍵列,因此若是主鍵列很大的話,其餘的全部索引都會很大。所以,若表上的索引較多的話,主鍵應當儘量的小。另外InnoDB的存儲格式是平臺獨立。
InnoDB作了不少優化,好比:磁盤讀取數據方式採用的可預測性預讀、自動在內存中建立hash索引以加速讀操做的自適應哈希索引(adaptive hash index),以及可以加速插入操做的插入緩衝區(insert buffer)等。
InnoDB經過一些機制和工具支持真正的熱備份,MySQL的其餘存儲引擎不支持熱備份,要獲取一致性視圖須要中止對全部表的寫入,而在讀寫混合場景中,中止寫入可能也意味着中止讀取。
MyISAM存儲引擎的特色和應用場景?
MyISAM是MySQL 5.1及以前的版本的默認的存儲引擎。MyISAM提供了大量的特性,包括全文索引、壓縮、空間函數(GIS)等,但MyISAM不「支持事務和行級鎖」,對於只讀數據,或者表比較小、能夠容忍修復操做,依然可使用它。
特性
MyISAM「不支持行級鎖而是對整張表加鎖」。讀取時會對須要讀到的全部表加共享鎖,寫入時則對錶加排它鎖。但在表有讀取操做的同時,也能夠往表中插入新的記錄,這被稱爲併發插入。
MyISAM表能夠手工或者自動執行檢查和修復操做。可是和事務恢復以及崩潰恢復不一樣,可能致使一些「數據丟失」,並且修復操做是很是慢的。
對於MyISAM表,即便是BLOB和TEXT等長字段,也能夠基於其前500個字符建立索引,MyISAM也支持「全文索引」,這是一種基於分詞建立的索引,能夠支持複雜的查詢。
若是指定了DELAY_KEY_WRITE選項,在每次修改執行完成時,不會當即將修改的索引數據寫入磁盤,而是會寫到內存中的鍵緩衝區,只有在清理鍵緩衝區或者關閉表的時候纔會將對應的索引塊寫入磁盤。這種方式能夠極大的提高寫入性能,可是在數據庫或者主機崩潰時會形成「索引損壞」,須要執行修復操做。
InnoDB與MyISAM對比
說了這麼多估計看一眼也沒記住,給你一張表,簡單羅列兩種引擎的主要區別,以下圖。
其餘存儲引擎
MySQL還支持其餘一些存儲引擎,好比memory引擎、NDB集羣引擎、CSV引擎,因爲這些引擎沒有上述InnoDB 和MyISAM 經常使用,這裏不做介紹,感興趣能夠去翻MySQL文檔瞭解。
再說兩句
這一篇是MySQL基礎篇,我力求用通俗易懂和圖表結合的形式給你們梳理這塊知識,越是基礎和底層的知識越容易被考察掌握程度,以上知識點均可能成爲面試中的一個考察點,相信看完對MySQL事務和存儲引擎應該有一個比較完整的理解。
最後
歡迎關注公衆號:程序員追風,回覆66 ,領取一份300頁pdf文檔的Java核心知識點總結!
這些資料的內容都是面試時面試官必問的知識點,篇章包括了不少知識點,其中包括了有基礎知識、Java集合、JVM、多線程併發、spring原理、微服務、Netty 與RPC 、Kafka、日記、設計模式、Java算法、數據庫、Zookeeper、分佈式緩存、數據結構等等。面試