Mysql进阶索引篇02——InnoDB存储引擎的数据存储结构(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 前面我们已经剖析了mysql中InnoDB与MyISAM索引的数据结构,了解了B+树的设计思想、原理,并且介绍了B+树与Hash结构、平衡二叉树、AVL树、B树等的区别和实际应用场景。页和页之间并不一定在物理上相连,只是在逻辑上使用双向链表关联。指针、记录究竟是如何存储的呢?其实这就需要联系我们之前提到的行格式了。数据查找在页目录中二分法快速定位到槽,上面的过程都与页的内部结构相关,本文将详细的阐述。

3.2 Compact行格式

compact是一种经典的行格式,它也是mysql5.1的默认行格式,我们把它作为讲解的重点介绍。其示意图如下。

现在我们对这个结构进行里的各个部分进行依次讲解。

3.2.1 变长字段长度列表

执行如下语句,创建一张新的数据表。

插入几条数据。

我们知道,在mysql数据库中,VARCHAR(M),VARBINARY(M),TEXT,BLOB类型都是变长的。我们在上面指定col1时设置的长度是8,单我们实际使用时字段长度可能并没有到8(如’tong’这个数据字段)。变长字段的长度列表其实就是需要记录字段实际存储的长度。


注意,变长字段列表记录存储长度的顺序与我们变量声明的顺序是反过来的。比如我们声明两个Varchar字段的顺序是a(15),b(10),那么变长字段列表的存储的长度顺序就是10,15.


上面插入的第一条数据长度对应转为16进制如下。

因此变长长度列表存储的内容为060408.如下图。

3.2.2 Null值列表

Compact行格式会把Null值列统一管理起来。当然,如果表中不允许存放Null值,那么Null值列表就不存在了。


为什么要定义Null值列表呢?这是因为mysql数据库中定义的数据是对齐的。比如我们现在存储了四个数据(‘a,’Null,Null,‘b’),我们在存储完a以后再存储b,那么在查找数据的时候不是会造成混乱么?当然,我们也可以把Null值数据存储的空间提前预留出来,但是这无疑会浪费空间。因此,我们在记录信息之前开辟了一块空间来存储Null值的位置。而且这个实现也很简单,我们只需要一个bit位来存储是否字段是空。如果是空则置为1,否则为0。


上面第1条记录的Null值列表如下所示。同样,Null值列表的记录顺序与字段声明的顺序是相反的,并且col2声明是指定了Not Null非空约束,不会在Null值列表中进行记录。另外,如果声明时指定了主键,由于主键一定非空,因此也不会在声明列表中出现。

3.2.3 记录头信息

我们先创建一张数据表。

然后插入一些数据。重点关注下这些数据的记录头信息.

我们将上面的字段介绍如下。


delete_mask:该记录是否被删除。如果这个值是0,说明记录没有被删除,否则说明记录被删除。

由此可知记录删除是采用的逻辑删除,这是因为我们记录之间是紧密相连的,如果真正删除一个记录,将会需要导致后面的记录依次进行位移。所有被删除的记录会通过next_record构成一个垃圾链表,它们所占用的空间称为可重用空间。


min_rec_mask:存储目录项记录中主键值最小的目录项记录置为1,其它情况都置0.


Record_type:记录类型,0表示普通记录,1表示B+树的非叶子节点(目录页节点)、2表示最小记录,3表示最大记录。


heap_no:表示当前记录在本页中的位置。我们注意到前面图片的第一条记录的heap_no是2,那么0和1呢?实际上,mysql会自动创建两条虚拟记录,即最小记录和最大记录。位于记录链表的最前面位置。由于这两个记录不是我们创建的,因此并没有存储在用户空间中,而是放在Infimum和Supermun部分。他们其实是相当于头尾节点。



n_owned:页目录中每个组的最后一条记录会存储该组的记录数,作为n_owned字段。值的关注的是,在mysql中最小记录是一组,普通记录与其它记录是一组,因此最小记录中n_owned属性是1,最大记录的n_owned值是5.


next_record:它表示当前记录的真实数据到下一个记录的真实数据之间的偏移量。


介绍完以上知识点,我们来举一个例子,比如我们需要删除第2条记录,那么记录行格式会发生什么变化呢?删除第2条记录后的示意图如下。可以看到,首先第2条记录的delete_mask将标记为1,next_record标记为0。它前一个节点第一条记录的next_record会指向第3条记录。同时最大记录中的n_owned属性值变为4.

3.2.4 真实数据

真实数据里除了真实列还存储了三个隐藏列。

实际上,这几个列的真实名字是DB_ROW_ID,DB_TRX_ID,DB_ROW_PTR。


我们在上一篇文章介绍InnoDB索引的时候提到过,如果表中无主键,也没有适合做主键的(声明了唯一标识)其它列,会隐式的指定一个聚簇索引。实际上,在这种情况下就是会添加一个row_id的隐藏列。另外两个隐藏列与事务相关,我们会在之后介绍事务的博客中再进行介绍。

3.3 Compact行格式存储实例剖析

上面我们已经介绍了行格式,现在根据具体的实例进行下剖析。创建数据表并插入数据。

找到对应的mytest.idb文件(注:推荐使用notepad++并安装使用Hex-Editor插件)

读出来的有效数据内容如下。我们采用不同颜色对于行格式的不同部分做了区分。

第一行中有03 02 01字段,这其实就是表中插入的第一条数据(‘a’,‘bb’,‘bb’,‘ccc’)的变长字段列表;

之后紧跟的00 是Null值列表,4个字段都非空的,因此这里使用的是00。倒数第二行中红色的06表示第三条插入数据中非空的数据的表示。因为'd',Null,Null,'fff'中四个数据分别用1,0表示是否为空的情况是0 1 1 0,倒过来仍然是0 1 1 0,转为16进制信息就是06.

之后的五个字节00 00 10 00 2c是记录头信息。其中2c就是next_record;

接下来的00 00 00 2b 68 00是隐藏主键DB_ROW_ID;

00 00 00 06 05是DB_TRX_ID;

接下来的7个字节80 00 00 00 32 01 10对应的回滚指针DB_ROW_PTR;

接下来的61对应真实数据a,62 62对应bb,62 62 20 20 20 20 20 20 20 20表示的是定长的bb,其中20表示没有真实数据,之后的63 63 63则表示ccc。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
26天前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
1月前
|
存储 关系型数据库 MySQL
MySQL存储引擎详述:InnoDB为何胜出?
MySQL 是最流行的开源关系型数据库之一,其存储引擎设计是其高效灵活的关键。InnoDB 作为默认存储引擎,支持事务、行级锁和外键约束,适用于高并发读写和数据完整性要求高的场景;而 MyISAM 不支持事务,适合读密集且对事务要求不高的应用。根据不同需求选择合适的存储引擎至关重要,官方推荐大多数场景使用 InnoDB。
71 7
|
1月前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
144 7
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
176 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
1月前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
64 9
|
2月前
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别
InnoDB和MyISAM均采用B+树索引,但在实现上有所不同。InnoDB的主键索引在叶子节点存储完整数据记录,辅助索引则存储主键值;而MyISAM的主键索引与数据文件分离,仅存数据地址,且主辅索引无区别,支持非唯一主索引。
55 1
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
2月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
7月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)