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

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

前言


前面我们已经剖析了mysql中InnoDBMyISAM索引的数据结构,了解了B+树的设计思想、原理,并且介绍了B+树与Hash结构平衡二叉树AVL树B树等的区别和实际应用场景。

页和页之间并不一定在物理上相连,只是在逻辑上使用双向链表关联。指针、记录究竟是如何存储的呢?其实这就需要联系我们之前提到的行格式了。数据查找在页目录中二分法快速定位到,上面的过程都与页的内部结构相关,本文将详细的阐述。

这篇文章将对InnoDB引擎的数据存储结构介绍,带大家熟悉数据库的页的存储结构与行格式,为之后的调优做准备。


1.数据库的存储结构:页

索引实际上是存储在文件上的,确切的说是存储在页结构中的。存储引擎负责数据的读、写操作,不同的存储引擎的数据格式可能不同。本文所介绍的数据库存储结构基于Mysql的InnoDB存储引擎。这也是我们实际工作中所使用的。

1.1 磁盘与内存交互的基本单位:页

InnoDB将数据划分为若干页,Mysql页的默认大小是16kb.可以使用下面的命令进行查看。

在sql server中,页的默认大小是8kb。Oracle中使用块*(Block)的概念来作为磁盘与内存的基本交互单位,块的大小可以是2kb,4kb,8kb,16kb,32kb和64kb。


这里我们强调,mysql中磁盘与内存交互的基本单位是页,这表示我们在磁盘与内存之间进行数据交互,最少是一页,并且每次交互都是整数页。即使我们数据存储只存储了一行,数据库I/O的操作单位也是一页。这样设计其实也是为了提高效率,毕竟I/O的时间消耗很大,不可能读、写一次数据就进行一次磁盘的I/O操作。


1.2 页上层结构

页的上层结构是,一个区会分配64个连续页,区的大小正好是1MB(16kb * 64)。

段由一个区或多个区组成。段是数据库的分配单位,比如我们创建一个表,就会创建一个表段,创建一个索引,就会创建一个索引段。总而言之,不同类型的数据库对象对应不同类型的段。


这里我们举一个例子,部队中能够与敌军战斗的基本单位是一个兵,就像数据库中内存与磁盘交互的基本单位是一个页。但是一场战争派出去的不可能只是一个兵,而是更大的单位,比如师。对应的,数据库内存分配的最小单位是一个块。


表空间(table space)是一个逻辑容器。表空间中存储的是一个或者多个段,每个段只能属于一个表空间。表空间又可以分为系统表空间,用户表空间,撤销表空间、临时表空间等。


2.页的内部结构

常见的页有数据页(保存b+树节点)、系统页Undo页事务数据页

页可以划分为如下的七个结构。

这七个结构的作用如下。

为了方便大家的理解,我们将他们归纳为三个部分,进行讲解。

2.1 文件头与文件尾

File Header与File Trailer主要是用于描述页的通用信息,用于页与页的交互或者数据的校验等。

  • FILE_PAGE_OFFSET:记录页编号,InnoDB可以通过页号唯一确定一个页。


FILE_PAGE_TYPE:代表当前页的类型,比如FILE_PAGE_UNDO_LOG(Undo日志页)、FILE_PAGE_TYPE_SYS(系统页)、FILE_PAGE_INDEX(索引页/数据页)。


FILE_PAGE_PREV与FILE_PAGE_NEXT上一页与下一页。


FILE_PAGE_SAPCE_OR_CHKSUM:校验和,对于一个较长的字符串,我们可以通过算法将其计算得到较短的字符串,即校验和,当我们需要比较两个长的字符串是否相等时,就比较他们校验和即可。同样我们也可以用校验和比较两个页是否相等。

文件尾页同样有校验和,它们是对应的。当我们对磁盘进行数据更新的刷盘执行I/O时,如果由于断电等原因导致数据传输中断,很可能一个页没有操作完。而页是数据库中磁盘与内存交互的基本单位,为了能够保证一致性,我们需要回滚或者将未写完的数据写完。我们如何判断是否写完呢?就是通过校验和。

具体的过程是:在内存向磁盘写入数据时,先更新File Header中的校验和,如果文件未正常写完,头尾校验和会不一致,如果未刷盘的数据有记录,就继续刷完,否则回滚。


FILE_PAGE_LSN:日志序列号,记录文件最后修改时对应的日志序列位置。尾部也有该字段,同样是为了校验页面的完整性。


2.2 记录部分:空闲空间、最大/小记录、用户记录

在最开始,我们会将已存储的数据按照行格式放到User Records,每插入一个数据,就会从Free Space申请一个记录大小的空间划分到User Records,直到Free Space都被转化为User Records空间,会申请一个新的页。User Records中的数据是按照单链表进行连接的。具体细节我们将在介绍行格式的用户头信息时介绍。


在介绍最小记录和最大记录之前,我们先思考一个问题,有必要对记录大小进行比较吗?当然是有必要的,因为我们的节点都是进行排序的。既然需要排序,就需要进行大小的比较了。那么,最大记录和最小记录的作用是什么呢?实际上,它就相当于记录的头、尾节点,这里我们先简单介绍,后面我们介绍完行格式,大家会对这部分理解更为深刻。在mysql中,最小记录与最大记录的格式非常简单,可以参考下图。

2.3 页目录与页头

page_decotory主要是为了方便数据进行二分查找。页目录是不是一开始就生成的呢?比如我们有1000条记录,是不是一开始就按照主键生成这1000条记录的页目录?这样做对于存储的占用显然是很高的。

实际上,mysql数据库做法如下。


将每页所有记录(包括最小记录与最大记录,不包含已删除记录)进行了分组,每个组取一个记录放入页目录中,占一个槽位(slot).最小记录单独为1组,最大记录所在组一般是有1-8条记录,其它组一般有4-8条记录。

每组的最后一条记录会存储一个n_owned属性,代表该组有几个记录。

页目录用于存储每组最后一个记录的地址偏移量。

下图表示了这个过程,其中每个记录的第一个字段就是n_owned.

现在我们已经知道页目录是如何生成的了,那么我们如何利用页目录进行数据的查找呢?实际上就是利用二分法对需要查找的数据与页目录中数据进行比较。比如一个数据确定比槽2的更大,比槽3的更小,那就可以去槽3所链接的分组4进行查找了。它会从槽2所链接的分组3最后一个记录指针链接到分组4的第一个元素,然后进行遍历查找。

接下来我们看看page header中记录了什么信息。这些信息大概了解下,主要是页的内部结构的一些信息。

其中PAGE_DIRECTION记录当前新插入记录是需要在上一条记录的前面还是后面插入。

2.4 从存储角度看普通索引和唯一索引有什么不同

我们到目前为止已经了解了页的内部结构和索引的数据结构。接下来我们深入思考一个问题。

普通索引和唯一索引有什么不同?

唯一索引指的是对索引字段加了唯一约束的索引,因此该字段不会重复。我们学习了页的存储结构以后知道,一般一个页默认大小是16kb,可以存放上千条记录,而且这些元素的存放是有序的,元素之间通过指针相连接。因此,普通索引一般只是在找到第一个元素后再多往后进行几次查找即可,其时间消耗并不大(真正消耗时间的是磁盘I/O)。


3.InnoDB行格式

3.1 行格式简介与操作sql

行格式就是记录的存储格式。

行格式一般有CompactDynamicCompressedRedundant几种。

可以使用如下的查询语句查询Mysql数据库的默认行格式。在mysql8与mysql5.7中,默认行格式都是dynamic

可以使用下列语句查询某个表实际使用的行格式。

使用如下语句可以在创建表时指定其行格式。

修改表的行格式。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
2月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
95 4
|
2月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
|
3月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
114 9
|
15天前
|
存储 关系型数据库 MySQL
介绍MySQL的InnoDB引擎特性
总结而言 , Inno DB 引搞 是 MySQL 中 高 性 能 , 高 可靠 的 存 储选项 , 宽泛 应用于要求强 复杂交易处理场景 。
53 15
|
5月前
|
存储 网络协议 关系型数据库
MySQL8.4创建keyring给InnoDB表进行静态数据加密
MySQL8.4创建keyring给InnoDB表进行静态数据加密
144 1
|
9月前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
1643 57
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
5月前
|
SQL 缓存 关系型数据库
使用温InnoDB缓冲池启动MySQL测试
使用温InnoDB缓冲池启动MySQL测试
102 0
|
10月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
337 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
9月前
|
存储 关系型数据库 MySQL
MySQL存储引擎详述:InnoDB为何胜出?
MySQL 是最流行的开源关系型数据库之一,其存储引擎设计是其高效灵活的关键。InnoDB 作为默认存储引擎,支持事务、行级锁和外键约束,适用于高并发读写和数据完整性要求高的场景;而 MyISAM 不支持事务,适合读密集且对事务要求不高的应用。根据不同需求选择合适的存储引擎至关重要,官方推荐大多数场景使用 InnoDB。
223 7

推荐镜像

更多