二、InnoDB记录存储结构
1.1 概述
MySQL中负责对数据进行读取和写入操作部分是存储引擎。在InnoDB 中一张表的默认大小是 16384B,即16KB。而记录的存储结构对于学习数据库底层原理来说是非常重要的。
1.2 行格式
InnoDB存储引擎有四种行格式,分别是:
- COMPACT(紧凑的)
- REDUNDANT(冗余的)
- DYNAMIC(动态的)
- COMPRESSED(压缩的)
1.2.1 COMPACT(紧凑的)
图示:
-
记录的额外信息
(1)变长字段长度列表
逆向存放变长字段(比如VARCHAR(M)、VARBINARY(M)、各种TEXT类型、各种BLOB类型)的字节数。
(2)NULL值列表
存放标记各个字段是否位NULL的列表,每一列对应一个BIT位,如果为NULL则为1,否则为0。
(3)记录头信息
名称 大小(字节) 描述 预留位 1 1 没有使用 预留位 2 1 没有使用 delete_flag 1 标记改记录是否被删除 min_rec_flag 1 B+ 数的每层非叶子节点中最小的目录记录都会添加该记录 n_owned 4 一个页会被分为多个组,每一组中会有一条记录的这个字段表示该组的条数,其余记录中该字段为0 heap_no 13 当前记录在堆中的位置 record_type 3 0表示普通记录;1表示B+ 数中非叶子节点的记录;2表示当前组的最小记录(Infimum);3表示当前组的最大记录(Supremum) next_record 16 表示下一条记录的绝对位置 -
记录的真实数据
(1)MySQL的隐藏列
列名 是否必须 字节大小 备注 ROW_ID 否 6 在用户没有自定义主键,且其它字段没有唯一性且不为空的情况下,InnoDB会为记录添加该字段 TRX_ID 是 6 事务ID ROLL_POINTER 是 7 回滚指针 (2)关于CHAR(M)类型字段的存储
我们知道CHAR(M)和VARCHA(M)的区别是CHAR(M)指定空间大小,且不可变,即使传入了一个字符也不会改变,VARCHA(M)分配的空间大小是小于M个字符。但是在不同的字符集下CHAR(M)的分配的空间大小是不同的,比如在**ascii**编码下,一个字节表示一个字符CHAR(M)占用固定的M个字节,在**gbk**编码下,1~2 个字节表示一个字符,CHAR(M) 占用 M~2M 个字节,在**utf-8**编码下,1~3个字节表示一个字符,CHAR(M)占用 M~3M个字节。此时我们的CHAR(M)字段的长度是否存储在变长字段长度列表和字符集,即编码格式有关。
1.2.2 REDUNDANT(冗余的)
图示:
概述:最古老的一种行格式,在MySQL5.0之前就已经使用
-
字段长度偏移列表
这里和COMPACT格式的区别就是它采用了偏移量的方式计算字段的长度
-
记录头信息
名称 大小(字节) 描述 预留位 1 1 没有使用 预留位 2 1 没有使用 delete_flag 1 标记改记录是否被删除 min_rec_flag 1 B+ 数的每层非叶子节点中最小的目录记录都会添加该记录 n_owned 4 一个页会被分为多个组,每一组中会有一条记录的这个字段表示该组的条数,其余记录中该字段为0 heap_no 13 当前记录在堆中的位置 n_field 10 记录中的列数 1 byte_offs_flag 1 标记字段长度偏移列表中每个列对应的偏移量是使用1字节还是2字节表示的 next_record 16 表示下一条记录的绝对位置
1.2.3 DYNAMIC(动态的)
和COMPACT格式不同点是:把所有的溢出数据都存储在溢出页中。
1.2.4 COMPRESSED(压缩的)
和COMPACT格式不同点是:把所有的溢出数据都存储在溢出页中,另外会采用压缩算法对页数据进行压缩。
1.3 执行和修改行格式的语法
CREATE TABLE 表名(列的信息)ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;