mysql笔记四:innodb行格式

关键字:行格式、记录头、行溢出

4.1、InnoDB的页简单介绍

数据是存储在硬盘上的,而数据处理是在内存中的。所以mysql处理数据时,需要将硬盘中的数据加载到内存中来,当有数据新增修改或删除时,需要将内存中的新的数据刷新到硬盘中去。mysql中数据在硬盘和内存之间交互时,并不是一条一条的数据交互,而是以页(Page)作为最小的基本单位,InnoDB中页的大小一般为16K。

4.2、InnoDB的行格式

mysql数据库中的每一条数据在硬盘中存储的方式是以行格式为基本格式存储的,也就是mysql数据库表中的每一条数据都是符合行格式的结构。

InnoDB有4种行格式,分别为:Compact行格式、Redundant行格式、Dynamic行格式、Compressed行格式。默认为Compact行格式,可以手动指定表的行格式。

4.3、Compact行格式

4.3.1、总结构

图中compact行格式表示了一条数据在mysql中存储的结构。

4.3.2、非null变长字段长度列表

       1)非null:数据不为null

       2)变长字段:对于varchar(M)、varbinary(M)、TEXT、BLOB等字段类型肯定是变长字段,对于char(M)这种字段类型,如果该列采用的字符集是变长编码方式的字符集,那么它也是变长字段,否则不是。

       VARCHAR(M)表示该列最多存储M个字符,不是M个字节。

       对于真实数据各列中所有非null的变长字段,数据占用的字节大小,组成一个列表,倒序排序存储在非null变长字段长度列表中。

       对于某一列的数据占用字节的大小小于255字节,那么就用1字节表示该列占用的字节大小。如果大于255字节,那么就使用2字节来表示该列占用的字节大小。

       非null变长字段的占用字节大小不可能超过2字节,因为一页数据最大是16k,行格式是存储在页中的,如果某列的数据长度过大,就会出现行溢出,在行格式里存储的数据字节数也很小,具体什么时候溢出,怎么溢出,溢出后行格式中存储什么,见4.6:行溢出数据。

4.3.3、null值列表

       对于表中允许出现null值的列进行统计,然后每一个列占用1个二进制位,按照倒序排序存储在null值列表,如果本条数据该列的值确实为null,则这个二进制位为1,如果不为null,则为0。

       null值列必须占用整数字节,如果列数小于8的n倍,则高位用0补齐。

4.3.4、记录头信息

       记录头信息总共占用5个字节,共40位。

(1)delete_mask

       标记该列数据是否被删除,0-未删除,1-删除。

       删除数据的delete mark阶段使用。

(2)min_rec_mask

       该记录是否是B+树中非叶子节点的最小记录,0-否,1-

(3)n_owned

       在数据页的的页目录(Page Director)中存放了数据的相对位置,这些记录称为槽(slots),InnoDB采用的是稀疏目录,一个槽对应着多条记录。InnoDB会将数据页中的记录划分为若干组,每一组的最大元素的数据位置会被提取到该数据页的页目录中,形成一个个槽,每个组中的最大记录的记录头信息的n_owned就表示了这个组中有几条数据。

       InnoDB规定,最小记录Infimum单独一个组,Infimum的n_owned的值永远为1,包含最大记录supremum的组的数据数量为[1,8],其他组数据数量为[4,8]。

       只有每组中最大记录的那条数据的记录头中n_owned有值,其余都是0。

(4)heap_no

       表示当前这条记录在这个页中的排位,最小记录infimum为0,最大记录supremum为1,其余我们的记录从2开始递增。(对于一条完整的记录,按主键大小进行排序)

(5)record_type(3位)

       表示当前记录的类型

       0:普通记录

       1:B+树非叶子节点记录

       2:表示页中最小记录Infimum

       3:表示页中最大记录Supremum

(6)next_record(16位)

       表示下一条记录的相对位置,next_record将页中所有记录串联成了一个单向链表。为什么不记录地址,而是记录相对位置,因为数据在硬盘上,没有地址。

4.3.5、隐藏列

       每条数据有2个或3个隐藏列。

       分别是DB_ROW_ID(主键列)、DB_TRX_ID(事务ID)、DB_ROLL_PTR(回滚指针)

       DB_ROW_ID:如果这个表没有主键且没有唯一二级索引,则会有这个隐藏列,否则没有,占用6字节。这个数据由Data dictionary Header的Max Row ID维护。

       DB_TRX_ID:占用6字节,表示这条数据最后修改的事务id,这个数据由TRX_SYS页的Max Trx ID维护。

       DB_ROLL_PTR:占用7字节,表示这条数据的上一条undo日志的位置。

4.3.6、真实数据

       这里只会存储非null列的真实数据,null列不会在这里体现。

4.4、Redundant行格式

Redundant是一种比较旧的行格式,为了兼容旧版本而留下来的。

4.5、Dynamic、Compressed行格式

Dynamic、Compressed行格式只是在处理行溢出时和compact行格式不一样,其他都一样。

4.6、行溢出数据

4.6.1、概念

当某条数据中某列的字节数过多时,mysql会在记录真实数据处只记录一部分数据,把剩余的数据存储到其他页中,然后在存储真实数据处用20个字节来存储这些页的地址,这种情况就称为行溢出。

4.6.2、行溢出的临界点计算

当某条数据中某列的字节数过多时,会发生行溢出,具体溢出的字节数就是临界点。

因为mysql中所有数据都存储在页中,页的大小为16k(16384字节),而每一页至少存储两条行数据。

假设,这个表中只有一列,计算方式:

132+2*(27+1*n) < 16384;

n<8099

所以对于一列的表,行溢出字节数是8099。

公式中:

132为页中其他数据占用大小

2为2条数据

27=2+1+5+6+6+7

4.6.3、行溢出后真实数据处存储的数据

对于compact行格式,真实数据处存储前768个字节+20个字节存储指向剩余数据页的地址,对于Dynamic和Compressed行格式,仅存储20个字节的指向剩余数据页的地址。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值