InnoDB(5)索引页 --mysql从入门到精通(十)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: InnoDB(5)索引页 --mysql从入门到精通(十)

上篇文章介绍了行溢出,表中最多创建65535个字节,而null值列表占用一个字节,变长字段长度列表占用两个字节,所以最长是65532个字节。而varchar(M)填写多少,要根据不同的字符集来规定,比如ascii一个字符是一个字节,gbk最大是2个字节,utf8最大是3个字节。数据也会溢出,数据溢出,则是会分成若干页存储,而compact行格式,真实数据列表会780左右字节,然后存页的地址值,方便查找剩余的真是数据。Mysql5.7后默认用dynamic行格式,而dynamic行格式在行溢出的情况下真实数据列表只存储页码地址值。Redundant则是会有压缩算法压缩页码分页,更节省空间。


InnoDB(4)行溢出--mysql从入门到精通(九)


回忆一下:


前面我们知道了查询一条数据,需要先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

插入之后存储的结果就是:

Delete_mark,min_rec_mask,n_owned,heap_no,record_type,next_record,C1,C2,C3,其他值

第一条记录:0,0,0,2,0,32,1,100,’aaaa’,其他值

第二条记录:0,0,0,3,0,32,2,200,’bbbb’,其他值

第三条记录:0,0,0,4,0,32,3,300,’cccc’,其他值

第四条记录:0,0,0,5,0,-111,4,400,’dddd’,其他值

上面都是前面说的 user records部分。


Delete_mark:占用一个二进制,0代表当前未删除,1代表已删除。所以在删除之后,磁盘上还是存在的,并不是数据就删除了,因为删除之后,大量的数据重排序消耗性能,而删除后的数据会组成一个垃圾链表,垃圾链表占用的空间称为可重用空间,之后有新的记录插入进来,可能吧这些删除记录占用的空间覆盖掉。(注意delete_mark标记删除 和 组成垃圾链表是两个步骤,后面在事务中会详情介绍~)

Min_rec_mask:B+树的每层非叶子节点最小记录都会添加该标记,目前四条记录都是0,代表他们都不是非叶子节点最小记录。

N_owned:一两句说不清,后面着重会详细介绍,稍安勿躁,铁汁们~

Heap_no:存储当前数据在当前页的索引地址,那为什么从2开始呢,0和1在哪,因为innoDB默认会给每个页自动添加两条虚拟数据,一个代表最小记录(infimum)和最大记录(supremum),他们比较大小的方式是按主键索引比较大小的,这两个是固定的数,所以此刻加上就变成了:

Delete_mark,min_rec_mask,n_owned,heap_no,record_type,next_record,C1,C2,C3,其他值

最小记录:0,0,1,0,2,28,infimum

最大记录:0,0,5,1,3,0,supremum

第一条记录:0,0,0,2,0,32,1,100,’aaaa’,其他值

第二条记录:0,0,0,3,0,32,2,200,’bbbb’,其他值

第三条记录:0,0,0,4,0,32,3,300,’cccc’,其他值

第四条记录:0,0,0,5,0,-111,4,400,’dddd’,其他值

从加粗斜体我们可以看到heap_no的索引值对应上了。

Record_type:0代表普通记录,1代表b+树非叶子节点记录,2,最小记录,3最大记录。可以看到我们插入的普通数都是0,而最小记录和最大记录代表2和3。

Next_record:记录下一条数据位子信息,比如我们删掉第二条记录之后,第二条记录和最大记录都会变成:


delete from index_page_tb where c1 = '2';
Query OK, 1 row affected (0.02 sec)


第二条记录:1,0,0,3,0,0,2,200,’bbbb’,其他值

最大记录:0,0,4,1,3,0,supremum

看结果可知,delete_mark已经为1已删除状态,并且next_Record也成了0,而且最大记录数的n_owned变为4。

若果insert 则会看到:


insert into index_page_tb values(2,200,'bbbb')
   -> ;
Query OK, 1 row affected (0.00 sec)


数据重新回到之前空间位子,因为删除的数据会组成垃圾链表,方便以后的数据重新利用空间。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
26天前
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别
InnoDB和MyISAM均采用B+树索引,但在实现上有所不同。InnoDB的主键索引在叶子节点存储完整数据记录,辅助索引则存储主键值;而MyISAM的主键索引与数据文件分离,仅存数据地址,且主辅索引无区别,支持非唯一主索引。
41 1
|
10天前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
57 7
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
141 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
16天前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
48 9
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
11天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
80 15
|
4天前
|
SQL 关系型数据库 MySQL
数据库数据恢复—Mysql数据库表记录丢失的数据恢复方案
Mysql数据库故障: Mysql数据库表记录丢失。 Mysql数据库故障表现: 1、Mysql数据库表中无任何数据或只有部分数据。 2、客户端无法查询到完整的信息。
|
11天前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
|
16天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
23天前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据
下一篇
DataWorks