Mysql 目前有 4 種行格式:Redundant、Compact、Dynamic、Compressed
Version 5.6 已經預設使用 Compact
Version 5.7 預設使用 Dynamic
Redundant 是比較老的資料格式,Compressed 不能應用在 System data;所以 Compact 和 Dynamic 應用較廣泛;
規定 (只討論 InnoDB):
1、儲存單元為頁 (page),16KB(16384B)
2、每頁至少需要存兩條資料
3、每條記錄都會有記錄頭
4、記錄幾乎都會有 3 個隱藏列 (rowId,transactionId,rollPointer)
Compact:
變長欄位 (記錄的長度) 列表 + NULL 列表 + 記錄頭資訊 + 列值
變長欄位 (記錄的長度) 列表:
採用 1-2 個位元組來表示一個欄位的長度,逆序;
欄位最大長度 <= 255 位元組用 1 個位元組表示;大於 255 位元組,但是實際使用位元組 <=127,也使用 1 個位元組來表示;其他情況使用 2 個位元組來表示;
char 如果是變長字符集 (GBK、UTF8) 也會需要使用變長欄位列表來儲存欄位使用的長度;
NULL 列表:
逆序,儲存每條記錄中允許為 NULL 的欄位,將實際為 NULL 的欄位用 1 表示,實際不為 NULL 的欄位用 0 表示;
每一列不是用一個位元組來表示,而是用一個位來表示;
記錄頭資訊:
使用 5 個位元組來表示;
主要包含:該記錄是否被刪除,記錄型別,下一條記錄的相對偏移量;
Redundant:
欄位長度偏移列表 + 記錄頭 + 列值
欄位長度偏移列表,用來記錄每列的結束位置;
真實資料 (整條記錄)<=127B 用 1 個位元組記錄,其他使用 2 個位元組;
是使用 1 個位元組還是 2 個位元組來儲存,該資訊放在記錄頭的 (1byte_offs_flag 屬性上)
每個列記錄的第一個 bit 使用來表示該列是否位 NULL;
Dynamic:
與 Compact 行格式很像,差異在於頁面溢位的處理上;
Compressed:
在於 Dynamic 使用了壓縮演算法;
頁溢位:
因為每頁 16KB,至少儲存兩行,所以每行大概有 8KB 的資料;拋開記錄頭資訊等,大致每列超過 768B 就會產生頁溢位;
Compact:
1、會將溢位的資料單獨放入一個頁;外加 20B 儲存額外頁的資訊 (plus the 20-byte pointer to the externally stored part)
2、索引可以使用前 768B
Dynamic:
2、如果頁溢位,則使用 20B 儲存整個列資訊 (列資料都儲存在溢位頁上)(with the clustered index record containing only a 20-byte pointer to the overflow page)
3、可以使用前 3072B 字元的索引 (–innodb-large-prefix 決定)
總的說來,Redundant 使用更多的位元組數量來儲存一條記錄 (欄位長度偏移列表),頁溢位會使用更多的 20B 來表示溢位部分(或整列) 資料,會使得索引資料更大;
本作品採用《CC 協議》,轉載必須註明作者和本文連結