SQL原理(2)| 青训营笔记

56 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天

具体数据存储

行数据

RedundantCompactDynamicCompressed.

  • Redundant 不紧凑,不用了
  • DynamicCompressed 这两个行格式跟 Compact 非常像
  • MySQL 5.1 版本之后,行格式默认设置成 Compact
  • MySQL5.7 版本之后,默认使用 Dynamic 行格式。
Compact

|800

  • 变长字段长度列表:说明所有 varchar(n) 的数据占用的大小(十六进制)(逆序存放)
    • NULL 不会存放在真实数据部分里的:varchar(n) 位置为 null,对应长度列表为空
    • 逆序存放: 和 「记录头信息」有关,方便一次性读取到靠前的记录
    • 数据表没有变长字段的时候,行格式就不会有「变长字段长度列表」

varchar(n) 中的 n 最大值
除了 TEXTBLOBs 这种大对象类型,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过 65535 个字节

  • 列值字节长度和字符集相关
  • 所有字段的长度 + 变长字段字节数列表所占用的字节数 + NULL值列表所占用的字节数 <= 65535
  • NULL 值列表:说明这些值为 NULL 的列(整数字节二进制位)(十六进制表示)(逆序存放)
    • 高位补 0+逆序存放
    • 当数据表的字段都定义成 NOT NULL 的时候,行格式就不会有 NULL 值列表
    • 建议将字段设置为 NOT NULL,这样可以至少节省 1 字节
  • 记录头信息:
    • delete_mask:数据是否被删除,detele 删除时delete_mask 标记为 1
    • next_record:下一条记录的「记录头信息」和「真实数据」之间的位置 ^3851fb
    • record_type:当前记录的类型,0表示普通记录,1表示 B+树非叶子节点记录,2表示最小记录,3表示最大记录(和数据页搭配)
  • 记录的真实数据:
    • 隐藏字段:
      • row_id:没有主键时添加,不必须
      • trx_id:事物用,必须
      • roll_pointer:记录上一个版本,必须
    • 真实数据:
      • 具体数据对应行.
行溢出处理
  1. Compact |600 真实数据处只会保存该列的一部分数据 → 剩余的数据放在「溢出页」中→ 真实数据处用 20 字节存储指向溢出页的地址

  2. Compressed 和 Dynamic |600 真实数据处不会存储该列的一部分数据 → 只存储 20 个字节的指针→ 实际的数据都存储在溢出页

页数据

InnoDB 的数据是按「数据页」为单位来读写的,InnoDB 数据页的默认大小是 16KB |600 |600 |600

  • 数据页构成双向链表,采用链表的结构是让数据页之间不需要是物理上的连续的,而是逻辑上的连续。(和“区”有关)![[#^f3f9e7]]
  • User Records 是行记录,数据页中的记录按照「主键」顺序组成单向链表(和“记录头数据”有关)![[#^3851fb]]
  • 页目录
    • 所有的记录划分成几个组,每个记录组的最后一条记录就是组内最大的那条记录
    • 页目录用来存储每组最后一条记录的地址偏移量 |600