InnoDB 將數(shù)據(jù)劃分為若干個(gè)頁,以頁作為磁盤和內(nèi)存之間交互的基本單位,InnoDB中頁大小一般為16KB。
系統(tǒng)變量
innodb_page_size表明了InnoDB存儲(chǔ)引擎中的頁大小,默認(rèn)值為16384字節(jié),該變量只能在第一次初始化MySQL數(shù)據(jù)目錄指定,之后不能修改了。
InnoDB 記錄格式
COMPACT,REDUNDANT,DYNAMIC,COMPRESSED
可以在創(chuàng)建表指定使用的行格式
CREATE TABLE demo (
c1 VARCHAR(10),
c2 VARCHAR(10) NOT NULL,
c3 CHAR(10),
c4 VARCHAR(10)
) CHARSET=ascii ROW_FORMAT=COMPACT;
或者修改表的語句中指定使用的行格式
ALTER TABLE 表名 ROW_FORMAT=行格式名稱;
COMPACT 格式

先插入2組數(shù)據(jù):
SELECT * FROM demo;
+---------+---------+---------+---------+
| c1 c2 c3 c4 |
+---------+---------+---------+---------+
| aaaa bbb cc d |
| eeee fff NULL NULL |
+---------+---------+---------+---------+
-
變長(zhǎng)字段長(zhǎng)度列表
MySQL 支持一些變長(zhǎng)的數(shù)據(jù)類型,比如VARCHAR,VARBINARY,各種TEXT類型,各種BLOB類型。這些數(shù)據(jù)列我們稱之為變長(zhǎng)字段。變長(zhǎng)字段中存儲(chǔ)多少字節(jié)的數(shù)據(jù)是不固定的,所以我們?cè)诖鎯?chǔ)真實(shí)數(shù)據(jù)的時(shí)候需要順便把這些數(shù)據(jù)占用的字節(jié)數(shù)也存儲(chǔ)起來。compact 行格式中,將其放在放在 變長(zhǎng)字段長(zhǎng)度列表中,各變長(zhǎng)字段的真實(shí)數(shù)據(jù)占用按照列的順序逆序存放。
變長(zhǎng)字段列為 c1 c2 c4,按照列的順序逆序存放,所以第一條記錄的變長(zhǎng)字段長(zhǎng)度就是:01 03 04
image.png -
NULL 值列表
一條記錄中某些列可能存儲(chǔ)NULL值,如果把這些NULL值都放到記錄的真實(shí)數(shù)據(jù)中存儲(chǔ)會(huì)很占地方,COMPACT 行格式把一條記錄中值為NULL的列統(tǒng)一管理起來,存儲(chǔ)到NULL值列表中,它的處理過程如下:首先統(tǒng)計(jì)表中允許存儲(chǔ)NULL的列有哪些 ?
主鍵列以及使用NOT NULL修飾的列都是不可以存儲(chǔ) NULL 的值,所以在統(tǒng)計(jì)時(shí)不會(huì)把這些列算進(jìn)去。上面就是c1,c3,c4列。-
如果表中沒有允許存儲(chǔ)NULL的列,則NULL值列表也就不存在了,否則將每個(gè)允許存儲(chǔ)NULL的列對(duì)應(yīng)一個(gè)二進(jìn)制位,二進(jìn)制位為1表示該列的值為NULL,否則表示不為NULL。同時(shí)MySQL 規(guī)定NULL值列表必須用整數(shù)各字節(jié)的位表示,如果使用的二進(jìn)制位個(gè)數(shù)不是整數(shù)個(gè)字節(jié),則在字節(jié)的高位補(bǔ)0
image.png所以上面的2條記錄NULL 值列表如下:
image.png
-
記錄頭信息
記錄頭信息由固定的 5 字節(jié)組成,用于描述記錄的一些屬性。名稱 大小 描述 預(yù)留位1 1 沒有使用 預(yù)留位2 1 沒有使用 deleted_flag 1 標(biāo)記該記錄是否被刪除 min_re_flag 1 B+樹的每層非葉子節(jié)點(diǎn)中最小的目錄項(xiàng)都會(huì)添加該標(biāo)記 n_owned heap_no record_type next_record -
記錄的真實(shí)數(shù)據(jù)
對(duì)于表來說,記錄的真實(shí)數(shù)據(jù)除了自己定義的外,MySQL還會(huì)為每個(gè)記錄默認(rèn)添加一些列(也稱為隱藏列)。名稱 是否必需 占用空間 描述 row_id 否 6字節(jié) 行ID,唯一標(biāo)識(shí)一條記錄 trx_id 是 6字節(jié) 事務(wù)ID roll_pointer 是 7字節(jié) 回滾指針 - InnoDB 主鍵生成策略
- 優(yōu)先使用用戶自定義的主鍵為主鍵。
- 如果用戶沒有定義主鍵,則選取一個(gè)不允許存儲(chǔ) NULL 值的 UNIQUE 健作為主鍵。
- 如果表中連不允許存儲(chǔ) NULL 值的 UNIQUE 健都沒有,則InnoDB則會(huì)為表默認(rèn)添加一個(gè)
row_id的隱藏列作為主鍵。
- InnoDB 主鍵生成策略
CHAR(M)列的存儲(chǔ)格式
對(duì)于CHAR(M)類型的列來說,當(dāng)列采用的是定長(zhǎng)編碼的字符集時(shí),該列占用的字節(jié)數(shù)不會(huì)被加到變長(zhǎng)字段長(zhǎng)度列表中,但是如果采用變長(zhǎng)編碼的字符集時(shí),該列占用的字節(jié)數(shù)還是會(huì)被加到變長(zhǎng)字段長(zhǎng)度列表。溢出列
REDUNDANT
過時(shí)了,這里不分析。
DYNAMIC
DYNAMIC, COMPRESSED和 COMPACT 格式挺像的,只不過在處理溢出列的時(shí)候。
COMPRESSED
不同于DYNAMIC,COMPRESSED 行格式會(huì)采用壓縮算法對(duì)頁面進(jìn)行壓縮,以節(jié)省空間。


