看完了MySQL小冊,我為何強烈推薦?
本文有福利相送,作為我鴿了這麼久的歉意。
總體上來說,是一本乾貨滿滿的價效比好書,從行文內容上也可以看出作者的功底,值得二刷三刷。(這本書貌似準備在機工出版了,已經說了半年了,估計就一個月之內了~)
我不是來寫軟文,也不是搞推薦,很純粹的分享一下最近看這本書的感受,這本書很適合會
CRUD
但對Mysq不甚瞭解的同學。簡單畫一個導圖給大家看一下這本書都講了什麼:
給各位一個福利 免費領取Java架構技能地圖 注意了是免費送
、
免費領取 要的+V 領取
我將小冊講訴的所有內容分為七部分,接下來我將根據導圖的各個部分說說我的看法。
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塊錢,價效比很高。
文章開頭也說了,本文有一點點福利,給大家抽三個小冊六折碼(非贊助,都是我之前參加徵文活動攢的),鑑於上次抽獎的教訓