前言
本文的觀點是基於MySQL使用Innodb存儲引擎的情況下進行的!
很多渠道說:MySQL數據按照主鍵大小依次排列,記錄之間是雙向鏈表連起來。如果說我告訴你這種說法很大程度上是錯的,你肯定說我在胡扯。
正文
我們先看看MySQL的B+樹索引結構是什么樣的
是的,這種圖和網上的很多圖都是類似的,我們可以看到每個節點上會有多個記錄或者數據,MySQL使用Innob引擎時,這個節點就代表的是Innodb頁,Innodb頁是最小的存儲單元。
通過上圖或者你以前就知道,一個Innodb頁存儲很多條數據。但是Innodb頁可不只有數據記錄,還會有其他數據。
上圖就是Innodb頁的結構圖
同樣每條記錄也不單單只有數據本身,還包含其他額外的數據
其中額外信息中,有記錄頭信息部分,這部分到底長什么樣呢
記錄頭占 5 個字節,40 位,下圖是對應代表的含義
- 1-2 位:預留,可以無視
- 3 位:在記錄剛被刪除時,不是馬上刪掉,而是將其標記為已刪除,實際還在占用空間
- 4 位:最小目錄項標記,B+樹是非葉子節點(每個節點是一個 Innodb 頁)內,最小目錄項標記
- 5-8 位:成員數量,Innodb 中,所有的記錄間不是無關的,也是要再次分組的,這里表示一個組的組長。舉個栗子,一個 Innodb 頁好比軍隊的一個排長,下面每個班長都帶個袖標,袖標上是班的人數
- 9-21 位:相對位置,表示本記錄在 Innodb 里的相對位置,可以簡單的認為(不准確)在一個頁里的第幾條記錄
- 22-24 位:記錄類型,一般記錄類型為普通類型,值為 0
- 25-40 位:下一條記錄的相對位置,是指本記錄距離下一條記錄開頭的真實位置,比如說,這里值為 64,就是從當前記錄真實記錄地址往后走 64 個字節,就是下一條記錄的真實數據
這里我們着重看一下下條記錄的相對位置部分:什么是相對位置呢?簡要回答就是我離你有多遠,而不是起點離你有多遠。放在MySQL里代表記錄之間的距離。
下面我們借助另一張圖看一下,看一下Innodb頁中記錄之間是怎么存儲的
上圖中我們看到,記錄之間是親密無間的排列的。那我們怎么找下一條記錄呢,還是看上面的出現的一張圖,里面的下條記錄的相對位置
比如,記錄1的中下條記錄的相對位置為38,意味着從記錄1的真實數據開始往后找38個字節就是下一條記錄的真實數據的開始。如果記錄1的下條記錄的相對位置是-38,代表從記錄1的真實數據部分往前找38個字節就是下一條記錄的真實數據部分。
如果你了解數據結構,你一定明白,這特么就是鏈表啊!是的,Innodb頁中的數據之間,是通過單向鏈表來實現的。
但是,Innodb頁之間是雙向鏈表關聯的。
一個Innodb頁中的文件頭中有這么兩個屬性:上一頁的頁號、下一頁的頁號
所以MySQL葉子節點之間是通過雙向鏈表完成的。
因此:記錄間可以說是既有單向鏈表又有雙線鏈表。