天天看點

(五十二)大白話不斷在表中插入資料時,實體存儲是如何進行頁分裂的?.md

上回我們講到了資料頁的實體存儲結構,資料頁之間是組成雙向連結清單的,資料頁内部的資料行是組成單向連結清單的,每個資料頁内根據主鍵做了一個頁目錄

然後一般來說,你沒有索引的情況下,所有的資料查詢,其實在實體層面都是全表掃描,依次掃描每個資料頁内部的每個資料行。

上述描述,其實就是沒有索引情況下在一個表中的資料查詢情況,這個速度可以說是慢到驚人,是以一般肯定是不能讓查詢走全表掃描的。是以正常在資料庫中的查詢,必須要運用到索引來加速查詢的執行。

但是今天還是沒法直接切入到索引這塊内容,因為作為前置知識,今天還得給大家講解另外一個知識點,就是我們在一個表裡不停的插入資料的時候,會涉及到一個頁分裂的過程,也就是說,這個表裡是如何出現一個又一個的資料頁的。

大家都知道,正常情況下我們在一個表裡插入一些資料後,他們都會進入到一個資料頁裡去,在資料頁内部,他們會組成一個單向連結清單,這個資料頁内部的單向連結清單大緻如下所示,我們看看

(五十二)大白話不斷在表中插入資料時,實體存儲是如何進行頁分裂的?.md

大家看上面的圖,裡面就是一行一行的資料,剛開始第一行是個起始行,他的行類型是2,就是最小的一行,然後他有一個指針指向了下一行資料,每一行資料都有自己每個字段的值,然後每一行通過一個指針不停的指向下一行資料,普通的資料行的類型都是0,最後一行是一個類型為3的,就是代表最大的一行。

上面就是一個典型的資料頁内部的情況,那麼今天要講的頁分裂是什麼意思呢?

是這樣的,假設你不停的在表裡插入資料,那麼剛開始是不是就是不停的在一個資料頁插入資料?接着資料越來越多,越來越多,此時就要再搞一個資料頁了,如下圖。

(五十二)大白話不斷在表中插入資料時,實體存儲是如何進行頁分裂的?.md

但是此時會遇到一個問題,後續我們會講到索引這塊機制,索引運作的一個核心基礎就是要求你後一個資料頁的主鍵值都大于前面一個資料頁的主鍵值,但是如果你的主鍵是自增的,那還可以保證這一點,因為你新插入後一個資料頁的主鍵值一定都大于前一個資料頁的主鍵值。

但是有時候你的主鍵并不是自增長的,是以可能會出現你後一個資料頁的主鍵值裡,有的主鍵是小于前一個資料頁的主鍵值的。

比如在第一個資料頁裡有一條資料的主鍵是10,第二個資料頁裡居然有一條資料的主鍵值是8,那此時肯定有問題了。

是以此時就會出現一個過程,叫做頁分裂,就是萬一你的主鍵值都是你自己設定的,那麼在增加一個新的資料頁的時候,實際上會把前一個資料頁裡主鍵值較大的,挪動到新的資料頁裡來,然後把你新插入的主鍵值較小的資料挪動到上一個資料頁裡去,保證新資料頁裡的主鍵值一定都比上一個資料頁裡的主鍵值大。

大家看下圖,假設新資料頁裡,有兩條資料的主鍵值明顯是小于上一個資料頁的主鍵值的,如圖所示。

(五十二)大白話不斷在表中插入資料時,實體存儲是如何進行頁分裂的?.md

如上圖所示,第一個資料頁裡有1、5、6三條資料,第二個資料頁裡有2、3、4三條資料,明顯第二個資料頁裡的資料的主鍵值比第一個資料頁裡的5和6兩個主鍵都小,是以這個是不行的。

此時就會出現頁分裂的行為,把新資料頁裡的兩條資料挪動到上一個資料頁,上一個資料頁裡挪兩條資料到新資料頁裡去,如下圖所示。

(五十二)大白話不斷在表中插入資料時,實體存儲是如何進行頁分裂的?.md

是以上述就是一個頁分裂的過程,核心目标就是保證下一個資料頁裡的主鍵值都比上一個資料頁裡的主鍵值要大。

這就是今天我們重點要講的頁分裂的過程,有了這個過程,保證了每個資料頁的主鍵值,就能為後續的索引打下基礎。

繼續閱讀