Mysql中每一行的實際數據在磁盤上是如何存儲的?


一行數據在磁盤文件里存儲的時候,實際上首先會包含自己的變長字段的長度列表,然后是 NULL值列表,接着是數據頭,然后接着才是真實數據,所以講講真實數據是如何存儲的。

首先我們在存儲真實數據的時候,按照字段里的數據值去存儲。

比如有一行數據是“jack NULL m NULL xx_school”,那么他真實存儲大致如下所示:

0x09 0x04 00000101 0000000000000000000010000000000000011001 jack m xx_school

剛開始先是他的變長字段的長度,用十六進制來存儲,然后是NULL值列表,指出了誰是NULL,接着是40個bit位的數據頭,然后是真實的數據值,就放在后面。

在讀取這個數據的時候,他會根據變長字段的長度,先讀取出來jack這個值,因為他的長度是4,就讀取4個長度的數據,jack就出來了;

  然后發現第二個字段是NULL,就不用讀取了;

  第三個字段是定長字段,直接讀取1個字符就可以了,就是m這個值;

  第四個字段是NULL,不用讀取了;

  第五個字段是變長字段長度是9,讀取出來xx_school就可以了。

但是,大家覺得真正在磁盤上存儲的時候,我們那些字符串就是直接這么存儲在磁盤上嗎?

顯然不是的! 實際上字符串這些東西都是根據數據庫指定的字符集編碼,進行編碼之后再存儲的,所以大致看起來一行數據是如下所示的:

0x09 0x04 00000101 0000000000000000000010000000000000011001 616161 636320 6262626262

我們的字符串和其他類型的數值最終都會根據字符集編碼,搞成一些數字和符號存儲在磁盤上 。

所以其實一行數據是如何存儲的,我相信大家就都已經了解的很清晰了,給大家簡單提一下,在實際存儲一行數據的時候,會在他的真實數據部分,加入一些隱藏字段,這個隱藏字段跟后續的一些內容是有關聯的。 首先有一個DB_ROW_ID字段,這就是一個行的唯一標識,是他數據庫內部給你搞的一個標識,不是你的主鍵ID字段。如果我們沒有指定主鍵和unique key唯一索引的時候,他就內部自動加一個ROW_ID作為主鍵。

接着是一個DB_TRX_ID字段,這是跟事務相關的,他是說這是哪個事務更新的數據,這是事務ID,這個后續我們講解到事務的時候會跟大家說的。

最后是DB_ROLL_PTR字段,這是回滾指針,是用來進行事務回滾的,也是我們后續在講解事務的時候再詳細說。 所以如果你加上這幾個隱藏字段之后,實際一行數據可能看起來如下所示:

0x09 0x04 00000101 0000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)
00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262

我給上面幾個隱藏字段都加了括號說明了,上面那基本就是最終在磁盤上一行數據是長成什么樣的了

我們再看看下面的圖,當你執行crud的時候,

  先會把磁盤上的數據加載到Buffer Pool里緩存,

  然后更新的時候也是更新Buffer Pool的緩存,同時維護一堆鏈表。

  然后定時或者不定時的,根據flush鏈表和lru鏈表,Buffer Pool里的更新過的臟數據就會刷新到磁盤上去。

 

 

 

現在我們思考一下,在磁盤上的數據,每一行數據是不是就是類似“0x09 0x04 000001010000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262”這樣的東西?

現在我們初步的把磁盤上的數據和內存里的數據給關聯起來了,他每一行數據的真實存儲結構就了解了,屢清楚這個他們之間的關系,其實這些都是有機一體的 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM