MySql-----InnoDB记录存储结构-----1

InnoDB记录存储结构

记录:就是一条信息

不同的存储引擎的记录存储结构是不一样的。

假如:

  每次存取数据都是一条一条的,那么就很浪费时间。

所以:

  将数据分为若干的页存储,每次存取都直接读一页,一页InnoDB默认的大小16KB

存放数据(一条记录)的格式:compact、redundant、dynamic、compressed

create table 表名 (列信息) row_format=行格式名称

alter table 表名 row_format=行格式名称

COMPACT行格式

变长字段长度列表

变长字段:varchar、varbinary、text、blob

把所有变长字段的真实数据占用的字节长度都存放在变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放;

例如:

create table demo(
   c1 varchar(10),
   c2 varchar(10) not null,
   c3 char(10),
   c4 varchar(10)
) charset=ascii row_fromat=compact;

insert into demo(c1, c2, c3, c4) values('aaaa', 'bbb', 'cc', 'd'), ('eeee', 'fff', null, null);

第一条数据:c3的char不是变长

列名 存储内容 内容长度 内容长度
c1 'aaaa' 4 0x4
c2 'bbb' 3 0x03
c4 'd' 1 0x01

所以变长字段长度列表为,注意是逆序的

可看出:变长字段长度列表是:3个字节表示;每一个字段用一个字节表示就行了

但是什么时候用两字节表示呢:

  如果可变字段允许存储的最大字节数超过255,并且真实存储的字节数超过127字节,那么使用两个字节,否则用1个字节

null值列表:

还是上述demo,c1、c3、c4可以为null,因为c2不可以为null,not null

对于第一条数据,没有null值

对于第二条数据:c3和c4都为null,所以值为1

假如一个表的可以为nul的字段超过了一个字节,那就用两个字节,反正高位补0⃣️

 记录头信息

名称  大小 描述
预留位1 1 没有使用
预留位2 1 没有使用
delete_mask 1 标记该记录是否被删除
min_rec_mask 1 B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned 4 表示当前记录拥有的记录数
heap_no 13 表示当前记录在记录堆的位置信息
record_type 3 表示当前记录的类型,0表死普通记录、1表示B+树非叶子节点记录、2表示最小记录、3表示最大记录
next_record 16 表示下一条记录的相对位置

记录的真实数据

假如表没有指定主键,则选取一个unique键作为主键,如果表中连unique键也没有指定,那么会innoDB会送一个row_id作为隐藏的主键。如果设置了主键,那当我没说

列名   是否必须 占用空间 描述
row_id 6字节 送的主键,表有就不送
transaction_id 6字节 送的事务ID
roll_pointer 7字节 送的回滚指针

Redundant格式

字段长度偏移表:

还是上面的例子;

row_id:6           0x06

transaction:12   0x0c

roll_pointer:19   0x13

c1:23               0x17

c2:26              0x1A

c3:36              0x24

c4:37              0x25

所以字段长度偏移列表:

  0x25 0x24 0x1A......0x06

记录头信息

没必要那么深究了

关于varchar行溢出

compact、redundant,会存储该字段的前768个字节,用20字节指向其他的存储页

dynamic和compressed:不会在该记录中存储,直接指向其他存储页面。

  

原文地址:https://www.cnblogs.com/sicheng-li/p/13112057.html