这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天
具体数据存储
行数据
Redundant、Compact、Dynamic 和 Compressed.
Redundant不紧凑,不用了Dynamic和Compressed这两个行格式跟 Compact 非常像- MySQL 5.1 版本之后,行格式默认设置成
Compact。 - MySQL5.7 版本之后,默认使用
Dynamic行格式。
Compact
- 变长字段长度列表:说明所有
varchar(n)的数据占用的大小(十六进制)(逆序存放)- NULL 不会存放在真实数据部分里的:
varchar(n)位置为null,对应长度列表为空 - 逆序存放: 和 「记录头信息」有关,方便一次性读取到靠前的记录
- 数据表没有变长字段的时候,行格式就不会有「变长字段长度列表」
- NULL 不会存放在真实数据部分里的:
varchar(n)中的n最大值
除了TEXT、BLOBs这种大对象类型,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过 65535 个字节
- 列值字节长度和字符集相关
- 所有字段的长度 + 变长字段字节数列表所占用的字节数 + NULL值列表所占用的字节数 <= 65535。
- NULL 值列表:说明这些值为 NULL 的列(整数字节二进制位)(十六进制表示)(逆序存放)
- 高位补 0+逆序存放
- 当数据表的字段都定义成 NOT NULL 的时候,行格式就不会有 NULL 值列表
- 建议将字段设置为 NOT NULL,这样可以至少节省 1 字节
- 记录头信息:
delete_mask:数据是否被删除,detele 删除时delete_mask标记为 1next_record:下一条记录的「记录头信息」和「真实数据」之间的位置 ^3851fbrecord_type:当前记录的类型,0表示普通记录,1表示 B+树非叶子节点记录,2表示最小记录,3表示最大记录(和数据页搭配)
- 记录的真实数据:
- 隐藏字段:
row_id:没有主键时添加,不必须trx_id:事物用,必须roll_pointer:记录上一个版本,必须
- 真实数据:
- 具体数据对应行.
- 隐藏字段:
行溢出处理
-
Compact
真实数据处只会保存该列的一部分数据 → 剩余的数据放在「溢出页」中→ 真实数据处用 20 字节存储指向溢出页的地址
-
Compressed 和 Dynamic
真实数据处不会存储该列的一部分数据 → 只存储 20 个字节的指针→ 实际的数据都存储在溢出页
页数据
InnoDB 的数据是按「数据页」为单位来读写的,InnoDB 数据页的默认大小是 16KB
- 数据页构成双向链表,采用链表的结构是让数据页之间不需要是物理上的连续的,而是逻辑上的连续。(和“区”有关)![[#^f3f9e7]]
User Records是行记录,数据页中的记录按照「主键」顺序组成单向链表(和“记录头数据”有关)![[#^3851fb]]- 页目录
- 所有的记录划分成几个组,每个记录组的最后一条记录就是组内最大的那条记录
- 页目录用来存储每组最后一条记录的地址偏移量