07.行记录结构
行记录分类:
Compact
Redundant
( < 5.0`)Dynamic
(默认)Compressed
Compact 行记录结构:
-
记录的额外信息
-
变长字段长度列表
- - 变长字段的定义: -
VARCHAR(M)
-
CAHR(M)
但字符集为变长字符集(除了ascii、latin1、utf32之外都是,见文末的字符集编码)
- 按照变长列的顺序倒序排列 -
使用1~2个字节,记录的是对应列真实
占用的字节数
- W
表示当前字符集的最多字节数(utf8mb4 1~4) -
VARCHAR(M)
这种类型表示能存储最多M
个字符
(注意是字符不是字节)
- 该类型理论最多占用的字节数就是M×W
-
实际占用字节数计做L
- 结论: - M×W <= 255 -
用1个字节表示 - M×W > 255,L <= 127 - 用1个字节表示 - M×W >
255,L > 127 - 用2个字节表示 - Null值列表
- - 按照Null值列的顺序倒序排列 -
用bit位记录的是对应列是否为Null,需要是字节的整数,不足在高位补0 -
记录头信息
- - 结构如下: - |名称|大小(单位:bit)|描述| |:–:|:–:|:–:|
|
预留位1
|1
|没有使用|
|预留位2
|1
|没有使用|
|delete_mask
|1
|标记该记录是否被删除|
|min_rec_mask
|1
|B+树的每层
非叶子节点中的最小记录都会添加该标记|
|n_owned
|4
|表示当前Page
directory分组拥有的记录数,仅分组内的最大记录存在该字段|
|heap_no
|13
|表示当前记录在记录堆的位置信息|
|record_type
|3
|表示当前记录的类型,0
普通记录,1
B+树非叶子节点记录,2
最小记录,3
最大记录|
|next_record
|16
|表示下一条记录的相对位置| -
记录的真实数据
- 隐藏列
- - 结构如下: - |列名|是否必须|占用空间|描述|
|:–:|:–:|:–:|:–:|
|
row_id
|否|6
字节|行ID,唯一标识一条记录|
|transaction_id
|是|6
字节|事务ID|
|roll_pointer
|是|7
字节|回滚指针,指向undo记录|
- 补充: - ** InnoDB
主键的生成策略 **: 1.
优先使用用户自定义主键,否则2 2.
选取一个Unique
键作为主键,否则3 3.
为表默认添加一个名为row_id
的隐藏列作为主键 -
用户数据列
- 真实的用户数据
Redundant 行格式:

Dynamic 行格式:
- 行溢出时处理方式跟
Compact
存在差异,其他类似
Compressed 行格式:
- 行溢出时处理方式跟
Compact
存在差异,其他类似;多页面进行压缩算法,节省空间,但消耗更多CPU
行溢出
:
MySQL
对一条记录占用的最大存储空间是有限制的(BLOB
、TEXT
除外,但会发生行溢出)所有列
(不包括隐藏列和记录头信息
)占用的字节长度在语法上加起来不能超过65535
个字节(否则语法报错),在使用上超过8098
字节会发生行溢出(不影响使用,语法不报错)- VARCHAR(M)理论存储的字符数量:
- M 表示存储的字符个数,不是字节数
- ASCII编码, M的最大值:
- VARCHAR(M) NOT NULL, M最多为65533 = (65535-2)/1
- 字节数最多为65535个
- 字段值长度占2字节
- ASCII每个字符需要1个字节
- VARCHAR(M) 没有定义NOT NULL, M最多为65532 = (65535-2-1)/1
- 字节数最多为65535个
- 字段值长度占2字节
NULL
值标识占1个字节- ASCII每个字符需要1个字节
- VARCHAR(M) NOT NULL, M最多为65533 = (65535-2)/1
- 不同编码下的M最大值:
行溢出
:单个记录
数据超过页的大小限制:- TEXT、BLOB类型的列在存储数据非常多的时候也会发生
行溢出
- 例如:VARCHAR(65532) 65533约64KB,超过单页16KB(16384字节)的限制
- 行记录格式针对
行溢出
的方案:- 对于
Compact
、Reduntant
,如果某一列中的数据非常多的话,在本记录的真实数据处只会存储该列的前
768个字节的数据
和一个指向其他页的地址
,然后把剩下的数据存放到其他页中。 - 对于
Dynamic
、Compressed
行格式,不会在记录的真实数据处存储数据的前768
个字节,而是把所有的字节都存储到其他页面
中,只在记录的真实数据处存储其他页面的地址
Compact
、Reduntant
行溢出:Dynamic
、Compressed
行溢出:
- 对于
行溢出的临界点
计算:- 假设:表结构只有一个字段(行记录只有一列)
- 规定:一个页中至少存放两行记录
- 数据推导:
- 每个记录至少27个额外字节;27 * 2
- 每个页的额外信息,136个字节
- 每个页最大16384字节
- 公式: 136 + 2×(27 + n) > 16384
- 求解后:n > 8098
- 如果我们向一个行中存储了很大的数据(超过8098个字节)时,可能发生
行溢出
的现象
- TEXT、BLOB类型的列在存储数据非常多的时候也会发生
字符集:
- MySQL有四个级别的字符集和比较规则:服务器级别、库级别、表级别、列级别
- 字符集 CHARSET:
- 作用:某个字符范围的编码规则
- 查看命令:SHOW CHARSET
- utf8mb3 (别名utf8):阉割过的utf8字符集,只使用1~3个字节表示字符,包含常用字符
- utf8mb4:正宗的utf8字符集,使用1~4个字节表示字符,包含所有字符
- 比较规则 COLLATION:
- 用来做排序和比较大小
- 查看命令:SHOW COLLATION [LIKE 匹配的模式]
- 字符集占用字节数: |字符集名称|Maxlen|备注| |:–:|:–:|:–:|
|
ascii
|1
|128个字符| |latin1
/ISO 8859-1字符集
|1
|256个字符| |gb2312
|1~2
|兼容ASCII,ASCII占1个字节,其他2字节,| |gbk
|1~2
|对GB2312字符集的扩充| |Unicode字符集
|1~4
|收录所有能想到的字符| |utf8
|1~4
|unicode字符集的一种编码方式| |utf16
|2、4
|unicode字符集的一种编码方式| |utf32
|4
|unicode字符集的一种编码方式|
本文作者:navyum
本文链接:https://www.cnblogs.com/navyum/p/18509413
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步