文章公號 首發!連載中~ 歡迎各位大佬關注, 回覆:“抽獎” 還可參加抽?活動
文末有二維碼
一、知識回顧
回顧一下之前和大家分享的知識點
看了前面的文章,想必你肯定了解了什麼是Buffer Pool、LRU-List、Free-List、Flush-List,你也知道了當MySQL增刪改查時,記憶體中發生了什麼,以及這幾個雙向連結串列是如何配合工作的。
通過閱讀上一篇文章你也一定了解了:你create出來的table其實是屬於一個表空間的,而所謂的表空間其實對應著一個真實存在於物理磁碟上的檔案。
並且在前面的文章中,白日夢曾不止一次的提及到:InnoDB從磁碟中讀取資料的最小單位是資料頁。而你想得到的id = xxx的資料,就是這個資料頁眾多行中的一行。
下面我們就一起看下,究竟什麼是MySQL的資料頁、資料區等概念。
二、資料頁長啥樣?
資料頁長下面這樣:
三、什麼是資料區?
在MySQL的設定中,同一個表空間內的一組連續的資料頁為一個extent(區),預設區的大小為1MB,頁的大小為16KB。16*64=1024,也就是說一個區裡面會有64個連續的資料頁。連續的256個資料區為一組資料區。
於是我們可以畫出這張圖:
從直觀上看,其實不用納悶為啥MySQL按照這樣的方式組織儲存在磁碟上的資料。
這就好比你搞了個Java的封裝類描述一類東西,然後再相應的給它加上一些功能方法,或者用golang封裝struct去描述一類物件。最終的目的都是為了方便、管理、控制。
約定好了資料的組織方式,那MySQL的作用不就是:按照約定資料規則將資料檔案中的資料載入進記憶體,然後展示給使用者看,以及提供其他能力嗎?
四、資料頁分裂問題
假設你現在已經有兩個資料頁了。並且你正在往第二個資料頁中寫資料。
關於B+Tree,你肯定知道B+Tree中的葉子結點之間是通過雙向連結串列關聯起來的。
在InnoDB索引的設定中,要求主鍵索引是遞增的,這樣在構建索引樹的時候才更加方便。你可以腦補一下。如果按1、2、3...遞增的順序給你這些數。是不是很方便的構建一棵樹。然後你可以自由自在的在這棵樹上玩二分查詢。
那假設你自定義了主鍵索引,而且你自定義的這個主鍵索引並不一定是自增的。
那就有可能出現下面這種情況 如下圖:
假設上圖中的id就是你自定義的不會自增的主鍵
然後隨著你將資料寫入。就導致後一個資料頁中的所有行並不一定比前一個資料頁中的行的id大。
這時就會觸發頁分裂的邏輯。
頁分裂的目的就是保證:後一個資料頁中的所有行主鍵值比前一個資料頁中主鍵值大。
經過分裂調整,可以得到下面的這張圖。
參考:
https://dev.mysql.com/doc/refman/5.7/en/glossary.html
關注送書!《Netty實戰》
文章公號 首發!連載中!關注微信公號回覆:“抽獎” 還可參加抽?活動
誠信第一,活動真實有效,抓緊上車,馬上開獎!