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

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

3.4 行溢出

我们在介绍另外两种行格式DynamicCompressed之前,先介绍下行溢出

InnoDB存储引擎可以将一条记录中的数据存储在真正的数据页面之外。下面将举例说明这一点,先创建一个数据表。

65535字节是VarCahr类型存储的最大长度,而ASCII码一个字符占一个字节,因此我们指定的VARCHAR(65535)就表示其存储的字符数是65535,这些字符占65535字节,正好是VARCHAR数据类型存储字节的上限。

如果您还不理解就可以不指定字符集试试。

上面的语句将会报错。

这是因为不指定字符集时,默认使用的是utf-8,一个字符占3个字节,因此存储的字符上限就是65535/3=21845。

言归正传,我们再来执行下最开始的建表语句。

居然还是报错了,错误信息如下。

这是为什么呢?其实是因为VARCHAR的数据是变长的,需要2个字节额外的空间来记录数据的长度,1个字节标识NULL值信息,因此存储空间不能够达到65535字节,只能达到65532字节。

当然,我们可以加上非空约束,这样就不用记录NULL值列表了。

我们之前介绍过一个页的大小是16kb,也就是16384字节,而现在我们一个字段就比它大。这就会导致行溢出

CompactRuduntant两种行格式中,对于占用空间非常大的列,在存储真实数据时只会存储真实数据的一部分。将剩余的数据存储到其它页中进行分页存储

3.5 Dynamic和Compressed行格式

Dynamic和Compressed行格式与Compact大体是相同的,不过这两种行格式对于行溢出的处理策略与Compact不同。

它们采取了完全行溢出的策略。也就是数据页不存储任何溢出真实数据,只是存储指针,将真实数据完全存储到其它页中。

Compressed还采用了zlib算法对数据进行压缩,因此对于BLOB、TEXT、VARCHAR等大长度类型的数据能够进行有效的存储。


3.6 Redundant行格式

Redundant是Mysql5.0之前InnoDB的行格式。Mysql5.0支持Redundant是为了兼容以前版本的页格式,其格式如下。我们可以对比之前Compact行格式。

我们可以发现,Redundant采用字段长度偏移列表来定位数据,而Compact采用变长字段长度列表和Null值列表。如果是Compact行格式,不是变长数据就不会记录变长字段长度列表。而Redundant行格式必须所有列(包括隐藏列)的偏移长度都逆序进行记录,因此其名字是Redundant(冗余的)。


另外,其存储的是字段与记录开始位置的偏移长度,不如变长列表直接存储长度直观。

另外,Redundant因为所有的字段的偏移长度都记录了,也不用担心Null值导致记录的位置对不起的问题,所以没有Null值列表。

其记录头信息如下,黄色是较Compact多的属性信息。它也没有Record_type属性。了解即可。


4.区、段和碎片区

4.1 为什么要有区

页与页是通过双向链表进行连接的,如果以页为单位分配存储空间,逻辑上相邻的两个页在物理磁盘上实际距离比较远。在进行范围查询时,如果页与页之间的距离过远,在进行磁盘I/O操作时加载页就需要花许多时间(寻道、旋转等),就是随机I/O。磁盘和内存的速度相差了好几个数量级,磁盘随机I/O会花大量时间在数据页的查找加载上,是非常慢的。


出于性能考虑,我们希望能够在相邻的位置存取数据,以便能够顺序读取数据页。当然,我们也不能够让所有数据都存储到连续的空间,毕竟越大的连续空间在磁盘上越难找到。因此我们引入了区的概念。一个区就是64个在物理空间上连续的页。因此一个区的大小是16KB * 64 = 1MB。在表的数据量大的时候,我们就不再以页为单位进行存储空间的分配了,而是连续分配一个区,甚至是多个区。


4.2 为什么要有段

一个区中存放的页可能是数据页或者目录页,但当我们进行范围查询时,感兴趣的只有普通数据页。如果因为存放了目录页的原因,导致范围查找的效果大打折扣。我们希望一个区存储数据页就存储数据页,存储目录页就只存储目录页,因此出现了段的概念。常见的段有数据段、索引段、回滚段。段是逻辑上的概念。由若干零散的页(碎片区中的页,下一节介绍)和完整的区所组成。


4.3 为什么要有碎片区

InnoDB存储引擎一个聚簇索引会生成两个段,数据段和索引段,而每个段是以区作为单位申请存储空间的,如果表的数据量只有几条,也需要申请2M的空间么(一个区的大小为1M)?而且每增加一个索引,又需要增加2M,这空间浪费的也太严重了。


因此提出了碎片区,在一个碎片区中,可以让多个段共用一个公共空间,一些页给段A,一些页给段B,让空间得到充分的利用。就好比一个大广场可以给体育生大篮球,也可以给大妈跳广场舞,但它不是任何人所独有,而是一块公共空间。

现在我们可以知道InnoDB存储引擎分配存储空间的具体策略了。


在刚向表中插入数据时,先使用碎片区以页为单位进行存储空间的分配。

当某个段占用的存储空间达到了32个碎片区以后,我们再以完整的区为单位分配存储空间。

4.4 区的分类

区大体可以分成四个类型。


空闲区(Free):现在还没有用到这个区的任何页面。

有剩余空间的碎片区(Free-Frag):表示碎片区中还有可用的页面。

没有剩余空间的碎片区(Full-Frag)。

附属于某个段的区(FSEG):专属于给某一个段使用的完整的区。

前三种类型的区都是独立的,直属于表空间。FSEG是属于段的。


5.表空间

表空间是一个逻辑上的容器。可以划分为:独立表空间,系统表空间,撤销表空间,临时表空间等。


5.1 独立表空间

每个表对应一个表空间,也就是一个表的索引和数据会被单独保存在自己的表空间中,可以在不同的数据库之间进行数据的迁移。


其空间回收也比较方便,可以通过Drop Table操作自动回收表空间。对于统计分析或者日志表,还可以在删除大量数据之后,通过alter table tableName engine=innodb回收不用的空间。这个特性使碎片空间不会太影响性能。


独立表空间的结构由段、区、页等组成,不再赘述。


一个新建表的.idb文件大小是96kb,也就是6个页面大小(Mysql5.7),当然随着数据量的增加,有些idb也是自扩展的,表空间的文件大小会变大。在mysql5.6后,默认使用的都是独立表空间。可使用下面的语句查询。

5.2 系统表空间

与独立表空间的结构基本类似,整个MySQL进程只有一个表空间,会额外记录一些关于整个系统的数据,这是独立表空间中所没有的。比如在information_schema中提供了以INNODB_SYS开头的一些表,用于帮助我们查看与数据库系统相关的信息(相当于数据字典的副本)。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
7月前
|
存储 SQL 关系型数据库
MySQL存储引擎简介
在选择相应的存储引擎时,需要充分考虑实际业务场景、性能需求和数据一致性要求,从而为数据管理提供最佳支持。
408 17
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
2061 57
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
9月前
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别?
首先两者都是用的是B+树索引,但二者的实现方式不同。 对于主键索引,InnoDB中叶子节点保存了完整的数据记录,而MyISAM中索引文件与数据文件是分离的,叶子节点上的索引文件仅保存了数据记录的地址. 对于辅助索引,InnoDB中辅助索引会对主键进行存储,查找时,先通过辅助索引的B+树在叶子节点获取对应的主键,然后使用主键在主索引B+树上检索操作,最终得到行数据;MyISAM中要求主索引是唯一的,而辅助索引可以是重复的,主索引与辅助索引没有任何区别,因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址
|
9月前
|
存储 关系型数据库 MySQL
MYSQL支持的存储引擎有哪些, 有什么区别
MYSQL存储引擎有很多, 常用的就二种 : MyISAM和InnerDB , 者两种存储引擎的区别 ; ● MyISAM支持256TB的数据存储 , InnerDB只支持64TB的数据存储 ● MyISAM 不支持事务 , InnerDB支持事务 ● MyISAM 不支持外键 , InnerDB支持外键
|
存储 关系型数据库 MySQL
MySQL存储引擎详述:InnoDB为何胜出?
MySQL 是最流行的开源关系型数据库之一,其存储引擎设计是其高效灵活的关键。InnoDB 作为默认存储引擎,支持事务、行级锁和外键约束,适用于高并发读写和数据完整性要求高的场景;而 MyISAM 不支持事务,适合读密集且对事务要求不高的应用。根据不同需求选择合适的存储引擎至关重要,官方推荐大多数场景使用 InnoDB。
559 7
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
625 7
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别
InnoDB和MyISAM均采用B+树索引,但在实现上有所不同。InnoDB的主键索引在叶子节点存储完整数据记录,辅助索引则存储主键值;而MyISAM的主键索引与数据文件分离,仅存数据地址,且主辅索引无区别,支持非唯一主索引。
254 1
|
3月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
172 3
|
3月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
856 152

推荐镜像

更多