Innodb記錄結構
- InnoDB記錄結構深度解析
- 一、InnoDB存儲基礎單元:頁(Page)
- 二、行格式(Row Format)
- 三、核心行格式詳解
- 1. Compact行格式
- 結構組成:
- 2. Redundant行格式(兼容舊版本)
- 核心差異:
- 3. Dynamic與Compressed行格式
- **適用場景差異**
- 四、行溢出處理機制
- 五、關鍵對比與選型建議
- 六、總結
InnoDB記錄結構深度解析
一、InnoDB存儲基礎單元:頁(Page)
-
頁大小:默認16KB,是InnoDB磁盤與內存交互的基本單位。
-
頁作用:所有數據讀寫操作以頁為單位,避免頻繁磁盤IO,提升性能。
二、行格式(Row Format)
InnoDB提供4種行格式:Compact、Redundant、Dynamic、Compressed。核心區別在于數據存儲方式和溢出處理機制。
三、核心行格式詳解
1. Compact行格式
結構組成:
-
變長字段長度列表(Variable-Length Field Length List)
-
逆序存儲:所有變長字段(如VARCHAR)的真實數據長度按列順序逆序存放。
-
長度表示規則:
-
-
若最大長度 ≤ 255字節,用1字節表示實際長度。
-
若最大長度 > 255字節,根據實際長度選擇1或2字節(L≤127用1字節,L>127用2字節)。
-
NULL值列表(NULL Value List)
-
二進制位圖:每個允許NULL的列對應1位(1表示NULL,0非NULL),按列逆序排列。
-
字節對齊:不足8位補0,例如3個NULL列用1字節(二進制高位補0)。
-
-
記錄頭信息(Record Header)
- 固定5字節,關鍵標志位:
-
delete_mask
:標記記錄是否被刪除。 -
next_record
:下一條記錄的相對位置(鏈表結構)。 -
record_type
:記錄類型(0-普通,1-B+樹非葉節點,2-最小記錄,3-最大記錄)。
-
真實數據(Real Data)
-
隱藏列:自動添加
row_id
(可選)、transaction_id
(事務ID)、roll_pointer
(回滾指針)。 -
CHAR(M)存儲:
-
-
定長字符集(如ascii):固定占用M×字符字節,不足填充空格。
-
變長字符集(如utf8):長度存入變長字段列表,至少占用M字節。
相比redundant的改進:
-
Compact僅存儲非NULL變長字段的實際字節長度(逆序排列),redundant存儲所有字段偏移地址
-
Compact使用位圖標記NULL列(每列1位),例如3個允許NULL的列僅需1字節存儲狀態。Redundant則通過偏移量高位標記NULL,每個允許NULL的列需額外占用偏移量空間
-
Compact頭信息5字節 包含
delete_mask
、record_type
等核心字段,支持更細粒度的記錄管理。redundant頭信息6字節,額外包含n_field
(列數量)和1byte_offs_flag
(偏移量字節數標識),缺少record_type
字段 -
發生行溢出:Compact保留768字節前綴,redundant無優化機制直接存額外頁導致更多空間碎片
2. Redundant行格式(兼容舊版本)
核心差異:
-
字段長度偏移列表:所有列(含隱藏列)的結束位置偏移量,逆序存儲,通過差值計算列長。
-
NULL處理:偏移量首比特標記NULL,定長列NULL仍占空間(填充0x00),變長列不占。
-
記錄頭信息:
-
6字節,含
n_field
(列數量)和1byte_offs_flag
(偏移量字節數標記)。 -
無
record_type
字段。
-
3. Dynamic與Compressed行格式
-
Dynamic:類似Compact,但所有溢出數據存于溢出頁,僅保留20字節指針。
-
Compressed:在Dynamic基礎上增加頁級壓縮,減少存儲空間。
適用場景差異
-
Dynamic的優勢場景:
-
適用于超長變長字段(如TEXT/BLOB),溢出數據占比高時,減少原始頁空間浪費。
-
不適用場景:若記錄長度普遍小于頁容量(16KB),Dynamic與Compact性能差異不大。
-
-
Compressed的優勢場景:
-
適合存儲成本敏感、讀多寫少的場景(如日志歸檔、歷史數據存儲)。
-
不適用場景:OLTP系統(高頻更新)、或CPU資源緊張時,壓縮開銷可能成為瓶頸。
-
四、行溢出處理機制
-
溢出條件:單行數據超過頁大小(16KB)閾值(約768字節后存溢出頁)。
-
溢出頁管理:
-
僅保留前綴數據(768字節)在本頁,剩余數據存入溢出頁。
-
通過指針鏈接溢出頁,保證主頁數據連續性。
-
五、關鍵對比與選型建議
特性 | Compact | Redundant | Dynamic |
變長字段存儲 | 僅變長字段長度列表 | 全字段偏移列表 | 類似Compact |
NULL處理 | 獨立NULL列表 | 偏移量首比特標記 | 同Compact |
溢出處理 | 部分保留前綴 | 同Compact | 全部存溢出頁 |
空間效率 | 高 | 較低 | 高 |
適用場景 | 常規OLTP | 舊系統兼容 | 大字段頻繁更新 |
格式 | 適用場景 | 不適用場景 |
Compact | 通用場景,短記錄為主,兼容舊版本 | 大字段頻繁訪問,存儲成本敏感 |
Dynamic | 超長變長字段(TEXT/BLOB),溢出數據占比高 | 記錄普遍短小,需避免溢出頁I/O開銷 |
Compressed | 讀多寫少,存儲成本敏感(如歸檔數據) | 高頻寫入、CPU資源緊張、OLTP系統 |
六、總結
-
行格式選擇:默認使用Dynamic(MySQL 5.7+),平衡空間與性能。
-
CHAR vs VARCHAR:
-
CHAR適合定長數據(如MD5),減少碎片。
-
VARCHAR節省空間,但頻繁更新可能產生碎片。
-
-
避免行溢出:大字段(如TEXT/BLOB)建議分離存儲或使用壓縮。
-
NULL優化:盡量使用NOT NULL,減少NULL列表開銷。
通過理解InnoDB記錄結構,可針對性優化表設計,提升存儲效率與查詢性能。