看完了MySQL小冊,我爲何強烈推薦?

本文有福利相送,作爲我鴿了這麼久的歉意。

總體上來說,是一本乾貨滿滿的性價比好書,從行文內容上也可以看出作者的功底,值得二刷三刷。(這本書貌似準備在機工出版了,已經說了半年了,估計就一個月之內了~)

我不是來寫軟文,也不是搞推薦,很純粹的分享一下最近看這本書的感受,這本書很適合會CRUD但對Mysq不甚瞭解的同學。

簡單畫一個導圖給大家看一下這本書都講了什麼:

給各位一個福利 免費領取Java架構技能地圖  注意了是免費送 

點我免費領取

我將小冊講訴的所有內容分爲七部分,接下來我將根據導圖的各個部分說說我的看法。

InnoDB

大家如果查看過這本小冊的目錄,可以發現其前四章都是關於一些基礎內容的,比如啓動Mysql-Server,使用Mysql-Client進行連接和更改字符集什麼的,所以這部分我並沒有標在導圖上,有一個大概瞭解就可以。

在這些基礎之後,就開始了小冊第一個硬菜:InnoDB原理的探究

InnoDB作爲我們最常用的Mysql存儲引擎,作者對它的筆墨也是最多的,因爲只有它支持事務,支持鎖,所以在這部分講述的很多內容都和後面的部分相呼應。

作者從一條記錄說起,給我們娓娓道來了InnoDB內部的數據管理方式:

一條數據庫表記錄會以一種叫記錄格式的方式存儲,以5.7爲例列舉了MySQL中四種行格式的不同組成結構及其特性。

記錄格式說完之後,又要說說記錄格式放在哪了?記錄格式放在一個名爲頁的數據結構上,MySQL中有很多不同的頁用以不同的用處。

每個頁是16KB大小,MySQL在讀取數據或者持久化數據的時候都是以頁爲基本單位,也就是說一次性最小會讀取或持久化16KB數據。

每次需要寫入數據時,都會向對應的數據頁申請內存,直至填滿之後會申請下一個頁,如果是刪除數據則會標記爲刪除,但是數據被刪除並不會移除此頁,而是被刪除的數據組成一個垃圾鏈表,等待新的數據來將其覆蓋

那麼頁說完了,頁又從屬於誰呢?這時又引入了表空間的概念。

一個表對應一個表空間文件(表名.ibd),這個表空間文件裏就是實際存放了數據的文件,數據記錄被頁管理,頁又被表空間管理,這是一個層層遞進的從屬關係。

但是因爲用表空間直接管理頁可以跨度太大(一個表空間對應所有表數據,但是一個頁才16KB,數據稍微大一點,就是一個表空間對應上萬甚至幾十萬的頁),所以表空間裏面又進行分層:區和組。

64個頁對應一個區(64*16=1MB),256個區又對應一個組(256MB),這樣劃分之後一個邏輯從屬關係就變成了:記錄->數據頁->區->組->表空間

同時爲了加快加載速度,幾乎所有系統都會用到的緩存就被引入了-緩存池。

緩存池的引入大大提高了數據頁查詢的效率,畢竟磁盤IO太太太慢了,緩存池會在MySQL啓動時申請一塊內存作爲數據頁的緩存池(數據庫優化的時候可以談談這個思路),同時根據算法來較好的控制緩存池裏的數據(最常訪問啊什麼的,這塊蠻複雜的)。

至此,InnoDB的基礎原理部分基本就是結束了,這部分我看下來最複雜的就是表空間部分,因爲涉及到諸如索引之類的東西,可以說表空間這節是整本小冊最難的,我看小冊評論區也都是如此想法。

索引

看小冊的時候本來就是抱着看索引的想法去的,但是沒想到索引的篇幅很短,只有兩章:索引原理和索引用法。

其實看小冊的時候,我一般都是對照着看的,看完作者寫的再去網上看看別人寫的,兩者結合起來去理解。

索引這塊也是如此,但是作者寫的真是蠻通俗易懂的,索引就是在行記錄的基礎上進行主鍵排序,因爲主鍵是有序的所以用主鍵作爲節點構成一顆B+樹,這顆B+樹的葉子節點就是所有的記錄,非葉子節點是一種名叫目錄樹的東西,可以理解爲對葉子節點進行分組用的,因爲是B+樹,所以使用二分查找可以很快的查找到對應節點。

這種非葉子節點直接是行記錄數據的索引被稱爲聚簇索引,這種索引會在InnoDB中自動生成,且因爲它葉子節點是所有的記錄,所以它也是很佔空間的東西。

我們手動進行生成的索引叫做二級索引/輔助索引,這種索引生成後也會構成一個B+樹,但是此樹葉子節點並不記錄行數據,而是記錄對應行數據的主鍵,當你用二級索引拿到主鍵後,還要用主鍵重新搜索一次數據,這個過程叫做回表。

如果創建二級索引時指定了多個列,這種索引叫做覆蓋索引。

除了這些作者還順帶講了MyISAM的索引,它沒有聚簇索引都是二級索引,但二級索引和InnoDB的又有些不同,MyISAM的索引中記錄的不是主鍵而是行號,可以通過對行號直接找到對應數據,這樣就少了一次回表過程。

懂了索引之後,再去看索引用法的注意事項就簡單多了~,比如:

索引列的類型儘量小(減少建立索引耗費的空間)

刪除表中的重複和冗餘索引(索引列只會用到一個索引)

數據庫主鍵自增(避免主鍵無序,這樣會頻繁打亂B+樹的節點,因爲B+樹依靠主鍵排序)

where 條件儘量索引字段的順序和創建聯合索引時字段順序一致(因爲覆蓋索引創建是按照多個索引字段值從左到右進行排序的)

模糊匹配指定左前綴可以用到索引(因爲索引值排序時是按照從左到右,所以如果左側值指定了也可以用到索引縮小範圍)

還有很多其他的注意事項,這塊網上基本說的都夠了,我這裏不再贅述,避嫌。

單表的訪問方式

單表的訪問方式,咋一聽很難理解的一個名詞,其實是MySQL的設計者給不同的查詢設立了不同的叫法,比如用主鍵查詢速度非常快,這種叫const,意爲常量級查詢,複雜度可以忽略掉。

這些都是一些知道了解的東西,因爲算是一種規定,同時這部分是Explain的鋪墊,Explain會用到這裏面的知識。

Explain

Explain的知識網上博客講的也很清楚了,因爲都是一些概念性的知識,我以前學MySQL的時候看的周陽的課,裏面也有講到Explain相關知識。

它主要是列出了一條查詢語句都走了哪些索引,影響了多少行數,個人覺得其實效用不大,因爲一條SQL交給執行器去執行之後,會有優化器進行優化,優化過的SQL可能已經和原來你編寫的不一樣了,需要了解優化器優化過程才能看懂這個。

這種情況你可以使用optimizer_trace去查看SQL的執行過程來知道優化器都做了哪些事。

也可以用其他方式比如:show status like '%last_query_cost%'

這條語句可以查詢上條查詢語句使用了多少成本,在SQL優化器對一個語句進行優化時會嘗試計算不同方案花費了多少成本,最終使用最少成本的那個優化方案,我覺得這種方式可以比較直觀的對比自己編寫的兩個SQL的性能差距。

子查詢優化

在優化器優化這塊,小冊主要講了優化器進行優化的一些方案,不過主要講的還是子查詢的優化方案。

事務

InnoDB基礎,索引,事務和鎖,可以說是看完這本小冊必須要瞭解的四大塊了。

事務裏的概念很多,ACID就不說了,既然是講原理的書,那作者的筆墨就主要用在MySQL用了什麼方案來保證事務和事務的回滾

MySQL使用redo日誌來記錄事務執行中的語句,用undo日誌記錄語句執行前記錄的值,同時每個事務都有一個全局ID。

redo日誌可以保證系統哪怕崩潰了,重啓回來之後還能根據裏面的日誌恢復到原樣,undo則可以保證需要回滾時有對應的記錄,undo還有一個作用,就是用來做MVCC。

MVCC(Mutil-Version Concurrency Control)-多版本併發控制,它是MySQL中用來解決併發讀寫的問題的一種方案。

在高併發的程序中,數據庫往往會同時開啓多個事務,執行過程中多個事務交替執行,這就可能會出現事務併發問題:髒寫,髒讀,不可重複讀和幻讀。

這裏我們再來複習一下這四個概念:

髒寫:一個事務修改了另一個未提交事務修改過的數據

髒讀:一個事務讀到了另一個事務未提交修改過的數據

不可重複讀:一個事務能讀到此事務開啓後其他事務提交修改的值

幻讀:一個事務中兩條同樣的查詢條件進行查詢時,後讀到的數據比前一次多

這四個問題都可以通過鎖來解決,但是這樣的話性能必然是會下降的,所以在MySQL中選擇這樣做:

髒寫一般是由鎖來完成的,也就是一個時間點只有一個事務對一條記錄進行寫,避免髒寫。

髒讀,不可重複讀,幻讀則可以由MVCC來控制,增強MySQL的併發性能,其原理是通過undo日誌維護了一個版本鏈,版本鏈每個版本上面都有一個事務id來標識這個版本是由哪個事務修改的,當前事務進行查詢時會根據當前事務id進行計算可以看到這個版本鏈上的哪些記錄,從而去避免髒讀,不可重複讀和幻讀。

網上有些解讀MVCC的時候說這是版本鏈+樂觀鎖,看了小冊之後我在網上翻到了MySQL中關於這塊的源碼,和小冊上面講訴的一樣,是通過計算(或者說判斷)來決定能看到哪個版本,樂觀鎖一般是比較新值和舊值,實際情況和樂觀鎖不太相像。

事務這塊看完之後,發現數據庫常問的MVCC也沒有那麼神祕,可以說是一句話就能說清的事。而且後來我忽然想起來seata這個分佈式事務的AT模式,它的原理實現其實就和MySQL裏面的事務原理幾乎是一樣的。

有了前面的鋪墊之後,看鎖這一章會簡單許多,但是小冊上面的鎖這一章僅僅是介紹了鎖的分類,也就是說平常MySQL在用鎖的時候一般會用到哪些鎖,他們分別有什麼特性,並沒有去深入的去分析兩個事務同時修改一條記錄的情況下鎖是怎麼做的。

但是並不是說作者沒寫,而是寫在公衆號裏面了,,,關注公衆號之後可以去看有三篇加鎖實戰分析的文章。

鎖其實可以通過兩個維度來劃分:粒度和特性。(當然這是我自己的理解)

粒度:根據影響的範圍可以分爲行級和表級。

特性:根據鎖的特性可以分爲獨佔或共享。

兩個維度組合一下一般就是四種:行級獨佔鎖、行級共享鎖、表級獨佔鎖和表級共享鎖。

除了這幾種鎖的具體實現,還介紹了鎖在內存中的結構,雖然我前面說了這章很重要,但我自己也沒有太過於細看,因爲都是概念性需要記憶的東西。

其實這章結合公衆號的加鎖實戰分析的文章是比較好的,這章就像是鎖實戰的先行知識,不然你直接去看鎖實戰,各種概念一上來恐怕給人搞得頭都大了。

小結

這篇文章給我寫的非常尷尬,因爲有很多想多寫出來的知識又不能寫(文章內容最多隻能由30%知識來源於小冊),所以我本來是想從邏輯上詳細給大家講講這本小冊的內容,但是又得避嫌(侵權啊,抄襲啊),最後就感覺有點虎頭蛇尾了(極力推薦查看我的導圖)。

不過像高頻率的一些知識點,我還是寫到的了,比如索引原理和事務原理(不過有點簡化),大部分開發應該是都沒有這個知識深度,如果能好好記憶下里面的內容,面試的時候其實可以往深了說,能把一點說深總比你說一堆淺顯易懂的知識點來的有用。

總體來說這本小冊還是比較推薦的,是一本深挖原理的書,有些知識點比如bin log這種偏應用層的沒有講到,其他的基本上都是很詳細了,用一下小冊優惠碼應該不到20塊錢,性價比很高。

文章開頭也說了,本文有一點點福利,給大家抽三個小冊六折碼(非贊助,都是我之前參加徵文活動攢的),鑑於上次抽獎的教訓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章