發布時間:2024-01-24閱讀(10)

學習關系型數據庫MySQL是很好的切入點,大部分人學習和工作中用慣了CRUD,對面試官刨根問底的靈魂拷問你還能對答如流嗎?我們有必要了解一些更深層次的數據庫基礎原理。
整理了面試中,關于MySQL事務和存儲引擎10個FAQ(Frequently asked questions),你想知道的都在這里。
事務就是「一組原子性的SQL查詢」,或者說一個獨立的工作單元。如果數據庫引擎能夠成功地對數據庫應用該組查詢的全部語句,那么就執行該組查詢。如果其中有任何一條語句因為崩潰或其他原因無法執行,那么所有的語句都不會執行。也就是說,事務內的語句,要么全部執行成功,要么全部執行失敗。
1BEGIN 或 START TRANSACTION 顯式地開啟一個事務;2COMMIT / COMMIT WORK二者是等價的。提交事務,并使已對數據庫進行的所有修改成為永久性的;3ROLLBACK / ROLLBACK WORK。回滾會結束用戶的事務,并撤銷正在進行的所有未提交的修改;4SAVEPOINT identifier 在事務中創建一個保存點,一個事務中可以有多個 SAVEPOINT;5RELEASE SAVEPOINT identifier 刪除一個事務的保存點;6ROLLBACK TO identifier 把事務回滾到標記點;7SET TRANSACTION 用來設置事務的隔離級別。InnoDB 存儲引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE
用銀行業務舉個栗子,用戶lemon有兩銀行卡,一張是招商銀行CMBC的工資卡,另一張是工商銀行ICBC的儲蓄卡,每月10號發工資都要把招行卡的100萬轉到建設銀行儲蓄卡賬戶。記住這里的銀行縮寫后面就是對應的數據表名稱,你要記不住,我給你理一理。
1招商銀行(CMBC):“存么?白癡!”2中國工商銀行(ICBC):“愛存不存!”3中國建設銀行(CCB):“存?存不?”4中國銀行(BC):“不存!”5中國農業銀行(ABC):“啊,不存!”6民生銀行(CMSB):“存么?SB!"7興業銀行(CIB):“存一百。”8國家開發銀行(CDB):“存點吧!”9匯豐銀行(HSBC):“還是不存!”

這個轉賬的操作可以簡化抽成一個事務,包含如下步驟:
以下語句對應創建了一個轉賬事務:
1STARTTRANSACTION;2SELECTbalanceFROMCMBCWHEREusername=lemon;3UPDATECMBCSETbalance=balance-1000000.00WHEREusername=lemon;4UPDATEICBCSETbalance=balance 1000000.00WHEREusername=lemon;5COMMIT;
ACID其實是事務特性的英文首字母縮寫,具體的含義是這樣的:

ACID
在事務A修改數據之后提交數據之前,這時另一個事務B來讀取數據,如果不加控制,事務B讀取到A修改過數據,之后A又對數據做了修改再提交,則B讀到的數據是臟數據,此過程稱為臟讀Dirty Read。

臟讀
一個事務內在讀取某些數據后的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了變更、或者某些記錄已經被刪除了。

不可重復讀
事務A在按查詢條件讀取某個范圍的記錄時,事務B又在該范圍內插入了新的滿足條件的記錄,當事務A再次按條件查詢記錄時,會產生新的滿足條件的記錄(幻行 Phantom Row)

幻讀
SQL實現了四個標準的隔離級別,每一種級別都規定了一個事務中所做的修改,哪些在事務內和事務間是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發處理,并擁有更低的系統開銷。

隔離級別
各個隔離級別可以不同程度的解決臟讀、不可重復讀、幻讀。隔離級別各有所長,沒有完美的解決方案,脫離業務場景談具體實施都是耍流氓。

隔離級別對比
MySQL中InnoDB和NDB Cluster存儲引擎提供了事務處理能力,以及其他支持事務的第三引擎。
MySQL默認采用自動提交AUTOCOMMIT模式。也就是說,如果不是顯式地開始一個事務,則每個查詢都被當作一個事務執行提交操作。
對于MyISAM或者內存表這些事務型的表,修改AUTOCOMMIT不會有任何影響。對這類表來說,沒有COMMIT或者ROLLBACK的概念,也可以說是相當于一直處于AUTOCOMMIT啟用的模式。
盡量不要在同一個事務中使用多種存儲引擎,MySQL服務器層不管理事務,事務是由下層的存儲引擎實現的。
如果在事務中混合使用了事務型和非事務型的表(例如InnoDB和MyISAM表),在正常提交的情況下不會有什么問題。
但如果該事務需要回滾,非事務型的表上的變更就無法撤銷,這會導致數據庫處于不一致的狀態,這種情況很難修復,事務的最終結果將無法確定。所以,為每張表選擇合適的存儲引擎非常重要。

最常用的存儲引擎是InnoDB引擎和MyISAM存儲引擎,InnoDB是MySQL的默認事務引擎。
查看數據庫表當前支持的引擎 :
1showtablestatusfromyour_db_namewherename=your_table_name;2查詢結果表中的`Engine`字段指示存儲引擎類型。
InnoDB是MySQL的默認「事務引擎」,被設置用來處理大量短期(short-lived)事務,短期事務大部分情況是正常提交的,很少會回滾。
更多InnoDB事務模型相關,參考MySQL官方手冊,這里貼一下鏈接:https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-model.html
現代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是MySQL 5.1及之前的版本的默認的存儲引擎。MyISAM提供了大量的特性,包括全文索引、壓縮、空間函數(GIS)等,但MyISAM不「支持事務和行級鎖」,對于只讀數據,或者表比較小、可以容忍修復操作,依然可以使用它。
MyISAM「不支持行級鎖而是對整張表加鎖」。讀取時會對需要讀到的所有表加共享鎖,寫入時則對表加排它鎖。但在表有讀取操作的同時,也可以往表中插入新的記錄,這被稱為并發插入。
MyISAM表可以手工或者自動執行檢查和修復操作。但是和事務恢復以及崩潰恢復不同,可能導致一些「數據丟失」,而且修復操作是非常慢的。
對于MyISAM表,即使是BLOB和TEXT等長字段,也可以基于其前500個字符創建索引,MyISAM也支持「全文索引」,這是一種基于分詞創建的索引,可以支持復雜的查詢。
如果指定了DELAY_KEY_WRITE選項,在每次修改執行完成時,不會立即將修改的索引數據寫入磁盤,而是會寫到內存中的鍵緩沖區,只有在清理鍵緩沖區或者關閉表的時候才會將對應的索引塊寫入磁盤。這種方式可以極大的提升寫入性能,但是在數據庫或者主機崩潰時會造成「索引損壞」,需要執行修復操作。
說了這么多估計看一眼也沒記住,給你一張表,簡單羅列兩種引擎的主要區別,如下圖。

引擎對比
MySQL還支持其他一些存儲引擎,比如memory引擎、NDB集群引擎、CSV引擎,由于這些引擎沒有上述InnoDB 和MyISAM 常用,這里不作介紹,感興趣可以去翻MySQL文檔了解。這里同樣給出官方鏈接:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html

引擎列表
這一篇是MySQL基礎篇,我力求用通俗易懂和圖表結合的形式給大家梳理這塊知識,越是基礎和底層的知識越容易被考察掌握程度,以上知識點都可能成為面試中的一個考察點,相信看完對MySQL事務和存儲引擎應該有一個比較完整的理解。
最后,感謝各位的閱讀,文章的目的是分享對知識的理解,若文中出現明顯紕漏也歡迎指出,我們一起在探討中學習。
https://book.douban.com/subject/23008813/
https://juejin.im/post/5c519bb8f265da617831cfff#comment
https://tech.meituan.com/2014/08/20/innodb-lock.html
https://blog.csdn.net/shellching/article/details/8106156
https://coolshell.cn/articles/6790.html
https://zhuanlan.zhihu.com/p/29166694
https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
https://www.zhihu.com/question/27876575
https://www.runoob.com/mysql/mysql-transaction.html
https://blog.csdn.net/qq_35642036/article/details/82820178?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
https://github.com/CyC2018/CS-Notes/blob/master/notes/MySQL.md#b-tree-原理
如果你想深入學習MySQL這里推薦一本個人認為講的比較好的圖書,《MySQL技術內幕:InnoDB存儲引擎(第2版)》這本書有多經典這里就不吹捧了,好的圖書是讀者口口相傳攢下的口碑,我只推薦自己讀過且認為寫的好的書,這本書豆瓣評分8.5

我學習MySQL的時候看過,非常佩服作者對InnoDB存儲引擎低層實現理解的這么透徹,讀完受益匪淺。
我會持續分享軟件編程和程序員那些事,歡迎關注。若你對編程感興趣,我整理了這些年學習編程的各種資源,關注我后私信發送【1024】免費獲取。

歡迎分享轉載→http://www.avcorse.com/read-218781.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖