MySql - 一條語句是怎麼插入磁盤的

咱們知道mysql插入語句後,都是存放在磁盤文件的,若是是多條數據的話,也是緊湊的挨在一塊兒,好比下圖:
image.png
可是實際上又有點不同,由於咱們建表的時候,有些字段的長度是可變的,好比咱們定義了varcher(10),可能就存了a,雖然能夠經過補齊長度來實現每條數據的長度是同樣的,但這樣就浪費了存儲空間,因此多條數據多是這樣存放的:
image.png
若是數據長度不同的話,那mysql讀取某一行的數據的時候,就很麻煩了,他不知道從哪裏開始從哪裏結束,因此每一條數據就包括兩個部分的內容,一個是描述這條數據的信息,一個是實際的數據。
image.png
描述數據有三個部分,分別是變長字段的長度列表、null值列表、數據頭。實際數據就是每一個字段的值緊湊的挨在一塊兒。因此實際上每行數據的結構是這樣的:
image.pngmysql

變長字段的長度列表

咱們建立表的時候,就會指定字段的類型,好比column1是可變字段的,這個時候變長字段的長度列表會記錄column1的長度,好比他的值是abc,那長度就是3,轉十六進制的話就是0x03,他的存儲是這樣的:
image.png
咱們讀取數據的時候,就能夠經過0x03知道column1要取多少數據。
若是column2也是可變字段,好比他的值是de,那他的存儲是這樣:
image.png
這裏須要注意的是,他的順序跟字段的順序是相反的。sql

null值列表

變長字段是用來知道咱們每一個字段實際的佔用長度,那null值字段其實就是代表哪些值是null的。由於某個字段是null的話,他實際上並不會存磁盤的,避免空間的佔用。是否爲空就兩種狀態,是或則不是,因此這裏有二進制來表示,1表示null,0表示非null。每個容許null的字段對應一位,位數是8的倍數,不夠就補零,因此咱們三個字段也是0000 0000。跟變長字段的長度列表同樣,他也是逆序的,即第一個字段在最後一位,因此咱們假設第一行的column3是null,那null值列表就是001,逆序就是100,補齊0就是0000 0100,那存儲是這樣的:
image.png
經過變長字段的長度列表咱們知道字段應該讀取的長度,經過null值列表咱們知道哪些字段應該忽略讀的。編碼

數據頭

數據頭有40位,後16位是next_record,他主要是記錄下一行的數據指針。
image.pngspa

實際數據

咱們存到磁盤的時候,會經過必定的字符集編碼進行對數據進行編碼,而後存放。
除了咱們定義的表字段外,他還有其餘的隱藏字段,好比DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR。
DB_ROW_ID是一行的惟一標識,若是沒有指定主鍵,那他的值就是主鍵。
DB_TRX_ID用於存放事務的ID。
DB_ROLL_PTR用於事務回滾。
因此實際的存儲以下(編碼這裏就略了):
image.png指針

相關文章
相關標籤/搜索