mysql innodb行內資料是如何儲存的?

時間 2022-01-04 08:10:33

1樓:從前慢慢慢慢死了

啥是儲存引擎呢? 簡單來說就是資料的儲存一般是在硬碟,而資料的處理一般是在記憶體,但是這兩者速度差距又比較大,勢必會影響處理速度,儲存引擎就是在這個問題上想了想辦法。 那具體是啥辦法呢?

我們需要處理資料時,要把資料都從硬碟搞到記憶體是不太現實,因為又不是都有用,再說了就是都有用空間也不應定夠,空間夠時間也不允許。所以就得一塊一塊的搞過來,InnoDB就是先把資料分了頁,一頁一般是16KB,一次就搞一頁到記憶體,或者從記憶體到硬碟。當然了這個頁的大小可以通過系統變數 innodb_page_size 設定。

需要注意的是這個只能第一次初始化資料目錄時指定(mysql --initialize)。

頁是 lnnoDB 中磁碟和記憶體互動的基本單位,也 lnnoDB 管理儲存空間的基本單位,預設大小為 16KB

下邊講的是頁裡邊存的東西。

資料在磁碟上存的格式為行格式(或記錄格式)。目前有4种行格式:COMPACT、REDUNDANT、DYNAMIC 和 COMPRSSED。

我們可以使用如下語句設定和更改表的行格式:

CREATE

TABLE表名(

列的資訊

)ROW_FORMAT

=行的格式

;ALTER

TABLE

表名ROW_FORMAT

=行的格式

;下面我們來介紹一下幾種行格式:

他主要由「記錄的額外資訊」和「記錄的真實資料」兩部分構成。大概長這個樣子:

額外資訊-變長字段長度列表儲存了一些變長的字段(VARCHAR、TEXTD等)他們的實際長度。進而組成了乙個變長字段長度列表,其中按照列的順序逆序存放。那具體來說,是用乙個位元組來表示實際長度還是兩個呢?

總體的原則呢要麼就是設定表結構時所設的最大長度就是小於255的那就用乙個沒問題。但是如果大於255,那就意味著這個變長字段可能用乙個位元組表示其長度,也可能用兩個。這就完蛋了,因為我們不知道是乙個還是兩個,所以要留出乙個位標識一下,也就是如果實際長度小於等於127就用乙個位元組,大於127就用2個。

(NULL 值不儲存)

額外資訊-NULL值列表所有允許儲存NULL 值的列都對應乙個二進位制位,是0說明不為空,1說明為空。這些二進位制位也是安照列順序逆序存放。儲存空間為整數個位元組,不足高位補零。

額外資訊-記錄頭資訊此部分固定為5個位元組的長度,不同位的資訊如下所示:

是不是有點多,看一眼漲漲見識吧,別為難自己。

真實資料此部分除了儲存實際的列資訊也會有隱藏列,如下:

其中我們發現row_id並不是必須的,為啥呢?因為InnoDB生成表的主鍵是先用使用者定義的,沒有就找不允許NULL且UNIQUE的,沒有就建立這個row_id的隱藏列作為主鍵。 接下來,就存真實列資料,NULL不存,固定長的字元沒有用完的位用空格補高位。

注意:對於CHAR(M),當用定長編碼集時不會加入到變長列表,當用變長編碼集時會加入變長列表。但對CHAR(M) 的列資料要求是至少佔M個位元組,對VARCHAR沒要求。

也就是說CHAR(10) 在編碼為utf8的列占用範圍為(10-30)

注意:REDUNDANT有點過時了,了解即可.

他的格式如下所示:

字段長度偏移列表記錄了包含隱藏列的字段偏移,依舊是按列順序逆序儲存記錄頭資訊 REDUNDANT 行格式多了 n_field(記錄中列的數量,n_field所佔大小10位) 和 1byte_offs_flag(記錄字段長度偏移列表中的偏移量是用乙個位元組還是兩個) 這兩個屬性,沒有了record_type這個屬性。

關於1byte_offs_flag的確定還是參考了真實資料的實際長度0-127 一位元組,128-0x7fff兩位元組。

NULL值要看列型別是否為變長,具體來說就是變長沒有值就是NULL不佔空間,但是不變長沒有值還是會佔空間,用0x00填充。至於如何表示NULL,使用的是字段長度偏移的首位表示。

溢位列是啥呢?我們在前邊說了一般MySQL乙個資料頁的大小是16k,我們介紹了半天介紹的是行格式,那這一頁存不下一行咋辦呢?就溢位了唄,這就是溢位列。

(MySQL規定的是一頁至少存兩行記錄,存不下兩行就會成為溢位列)

DYNAMIC 行格式是MySQL5.7預設的行格式,這兩個行格式和我們介紹的COMPACT行格式比較像。他們相較於COMPACT主要是對溢位列的處理不同,COMPACT當發生溢位時會先存一些真實資料,有一部分放入溢位列,然後記錄溢位列的位址和剩餘大小; 這兩種行格式是都把真實資料放到溢位列,只記錄溢位列的位址和剩餘大小。

另外,COMPRESSED 對真實資料做了壓縮處理。

2樓:Tony

CMU這個教程很清晰,對於所有資料庫的Leaf Node的結構是個總體的囊括

細節詳細看Leaf Node那節

cmu.edu/fall2019/slides/07-trees1.pdf還有這個關於Tuple如何在Page裡儲存的https:

//15445.courses.cs.cmu.edu/fall2019/slides/03-storage1.pdf

3樓:整天關心小事

主要的原因是設計上 primary key 有序,以加快查詢速度,例如在 order by、range、jion 等場景資料有序查詢效率會大大提公升。

mysql innodb換成myisam後插入資料變快?

流念 myisam沒有事務支援,它的連續的插入和查詢速度都比Innodb快很多,但是如果需要插入和查詢穿插著來,那麼myisam是表鎖,innodb是行鎖,innodb的併發性好,並且innodb是支援事務的 innodb在插入資料的時候需要維護表級快取,myisam只需要維護索引 檔案級offse...

mysql innodb如何檢視鎖?

愛可生雲資料庫 以下五種方法可以快速定位全域性鎖的位置,僅供參考。方法1 利用 metadata locks 檢視 此方法僅適用於 MySQL 5.7 以上版本,該版本 performance schema 新增了 metadata locks,如果上鎖前啟用了元資料鎖的探針 預設是未啟用的 可以比...

面板資料模型(Fe or Re)如何進行內生性檢驗?

Luna 先用理論定性分析初步確定內生變數X,找到它的工具變數,然後忽略變截距,直接在pool模型基礎上做2SLS,接著做可以允許異方差 可以搞定隨機效應下的情況 的Durbin Wu Hausman 簡稱DWH 檢驗,也就是Hausman內生性檢驗的公升級版,可以檢驗是否X具有內生性,當然工具變數...