1.InnoDB頁的簡介
頁(Page)是 Innodb 存儲引擎用于管理數據的最小磁盤單位。常見的頁類型有數據頁、Undo 頁、系統頁、事務數據頁等
2.InnoDB行的存儲格式
我們插入MySQL的記錄在InnoDB中可能以4中行格式存儲,分別是Compact、Redundant、Dynamic和Compressed行格式,我們可以在創建或修改表的語句中指定我們想要的行格式
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名稱ALTER TABLE 表名 ROW_FORMAT=行格式名稱
2.1 COMPACT行格式
Compact行記錄是在MySQL5.0中引入的,為了高效的存儲數據,簡單的說,就是為了讓一個頁(Page)存放的行數據越多,這樣性能就越高
一條完整的記錄被分為記錄的額外信息和記錄的真實數據兩大部分
2.1.1 記錄的額外信息
這些額外信息分為3類,分別是變長字段長度列表、NULL值列表和記錄頭信息。
2.1.1.1 變長字段長度列表
逆序記錄每一個列的長度,如果列的長度小于 255 字節,則使用一個字節,否則使用 2 個字節。該字段的實際長度取決于列數和每一列的長度,因此是變長的
2.1.1.2 NULL值列表
一個字節,表示該行是否有 NULL 值。注意:此處需要注意固定長度 CHAR 數據類型和變長 VCHAR 數據類型在 Compact 記錄下為 NULL 時不占用任何存儲空間。
2.1.1.3 記錄頭信息
用于描述記錄的記錄頭信息,它是由固定的5個字節組成。5個字節也就是40個二進制位,不同的位代表不同的意思,其中 next_record 記錄了下一條記錄的相對位置,一個頁中的所有記錄使用這個字段形成了一條單鏈表。
2.1.2 記錄的真實數據
MySQL會為每個記錄默認的添加一些列,除了記錄每一列對應的數據外,還有隱藏列,它們分別是 Transaction ID、Roll Pointer 以及 row_id(當沒有指定主鍵)
2.1.2.1 row_id
當用戶沒有設置主鍵,并且沒有unique屬性時,innoDB會隱式的生成一個row_id,作為主鍵
2.1.2.2 transaction_id 和 roll_pointer
用來記錄當前記錄的事務號,用于可重復讀隔離級別的樂觀鎖實現
2.2 Redundant行格式
MySQL5.0之前的行記錄格式:
2.2.1 字段長度偏移列表
與 Compact 中的變長字段長度列表相同的是它們都是按照列的逆序順序設置值的,不同的是字段長度偏移列表記錄的是偏移量,每一次都需要加上上一次的偏移,同時對于 CHAR 的 NULL 值,會直接按照最大空間記錄,而對于 VCHAR 的 NULL 值不占用任何存儲空間。
與compact行格式的不同在于:
- 存儲的是所有屬性的長度
- 長度是通過兩個相鄰偏移量的差計算得出的
- 使用了每個列對應偏移量的第一位作為NULL比特位來標記空值,并且對于真實記錄為NULL的定長字段也要使用0比特填充,變長則不用
- 對于char(M)來說,即使使用變長字符集,通通按照字符集的最大字符長度來分配空間
2.2.2 記錄頭信息
和compact的大致相同
行溢出數據
我們知道數據頁的大小是 16KB,Innodb 存儲引擎保證了每一頁至少有兩條記錄,當行記錄的長度沒有超過行記錄最大長度時,所有數據都會存儲在當前頁。如果一頁當中的記錄過大,會截取前 768 個字節存入頁中,其余的放入 BLOB Page。
然后記錄的真實數據處用20個字節存儲指向這些頁的地址(當然這20個字節中還包括這些分散在其他頁面中的數據的占用的字節數),從而可以找到剩余數據所在的頁
2.3 Dynamic和Compressed行格式
InnoDB1.0x開始引入心的文件格式(file format,用戶可以理解位新的頁格式)——Barracuda,這個新的格式擁有兩種新的行記錄格式:Compressed和Dynamic。
新的兩種記錄格式對于存放BLOB中的數據采用了完全的行溢出的方式。
-
Dynamic行格式,列存儲是否放到off-page頁,主要取決于行大小,他會把行中最長的一列放到off-page,直到數據頁能存放下兩行。TEXT或BLOB列<=40bytes時總是存在于數據頁。這種方式可以避免compact那樣把太多的大列值放到B-tree Node(數據頁中只存放20個字節的指針,實際的數據存放在Off Page中,之前的Compact 和 Redundant 兩種格式會存放768個字前綴字節)。
-
Compressed物理結構上與Dynamic類似,Compressed行記錄格式的另一個功能就是存儲在其中的行數據會以zlib的算法進行壓縮,因此對于BLOB、TEXT、VARCHAR這類大長度數據能夠進行有效的存儲(減少40%,但對CPU要求更高)。