InnoDB(5)索引页 --mysql从入门到精通(十)
上篇文章介绍了行溢出,表中多创建65535个字节,而null值列表占用一个字节,变长字段长度列表占用两个字节,所以长是65532个字节。而varchar(M)填写多少,要根据不同的字符集来规定,比如ascii一个字符是一个字节,gbk大是2个字节,utf8大是3个字节。数据也会溢出,数据溢出,则是会分成若干页存储,而compact行格式,真实数据列表会780左右字节,然后存页的地址值,方便查找剩余的真是数据。Mysql5.7后默认用dynamic行格式,而dynamic行格式在行溢出的情况下真实数据列表只存储页码地址值。Redundant则是会有压缩算法压缩页码分页,更节省空间。
回忆一下:
前面我们知道了查询一条数据,需要先tcp/ip先客户端链接服务端,之后会查询缓存,有的话直接返回,insert 和update都会让缓存失效,解码sql,优化sql,再访问我们现在说的存储引擎。而字符集的解码sql会发生乱码,所以用set names可以让charater_Set_client ,character_set_connection,character_set_results都设置成相同的字符集,提高效率,减少编码解码性能消耗。而存储引擎innoDB存储分为几个部分,变长字段长度列表,null值列表,头部信息列表,之后就是真实存储数据列表,当数据太多,就会分页存储,每页大概16kb。Compact和dynamic行格式不同,dynamic是当存在分页情况,是在真实数据只存指向页面的地址值,来查询数据,mysql5.7后默认的就是dynamic,行溢出和数据溢出也需要了解。
现在我们就要着重看看存放 数据的“index页”是什么?
存放我们表中记录类型的页,官方称为INDEX页(索引页),这些表中的内容就是我们日常存储的数据,所以又称为数据页。
innoDB数据页16kb大小存储空间可以划分为多个部分,不同部分有着不同的功能,
File Header:38个字节,文件头部,页的一些通用信息。
Page Header:56个字节,页面头部,数据页(index页)专有的信息。
Infimum+supremun:26个字节,小记录和大记录,两个虚拟行记录。
User records:大小不确定(看存储的数据),用户记录,实际存储的行记录内容。
Free space:大小不确定,空间空间,页中尚未使用的剩余空间。
Page directory:大小不确定,页面目录,页中某些记录对应的位子,地址值。
File Trailer:8个字节,文件尾部,效验文件是否完整。
注意:每个页中一开始并没有user records空间,是存入行数据开始,会从free space里的空间申请,分配一部分给user records存储数据,直到free space没有剩余空间,这时候就会申请新的页。
我们之前都介绍过变长字段长度列表和null值列表,唯独没有介绍头部信息列表,先回顾一下头部由什么组成?
预留位1:1bit,没有使用。
预留位2:1bit,没有使用。
Delete_mask:1bit,标记当前行是否被删除。
Min_rec_mask:1bit,B+树每层非子叶节点小记录都会添加该标记。
N_owned:4bit,表示当前记录拥有的记录数。
Heap_no:13bit,表示当前记录堆的位子信息。
Record_type:3bit,表示当前记录的类型,0代表普通类型,1代表B+树非叶节点记录,2表示小记录,3表示大记录。
Next_record:16bit,表示下一条记录的位子。
创建 一个表,指定字符集是ascii ,行格式为compact,主键指定为c1,所以当前只会有transaction_id事务id和roll_pointer回滚指针两个隐藏列,row_id隐藏列不存在,插入几条数据:
create table index_page_tb(
-> c1 int,
-> c2 int,
-> c3 varchar(1000),
-> primary key(c1)
-> )charset=ascii row_format=compact;
Query OK, 0 rows affected (0.07 sec)
//插入数据
mysql> INSERT INTO index_page_tb VALUES(1, 100, 'aaaa'), (2, 200, 'bbbb'), (3, 300, 'cccc'), (4, 400, 'dddd');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
相关文章