MySQL高级第四篇:InnoDB存储结构之页、区、段和表空间
迪丽瓦拉
2025-05-29 12:39:32
0

MySQL高级第四篇:InnoDB存储结构之页、区、段和表空间

  • 一、数据库的存储结构:页
    • 1. 页是磁盘与内存交互的基本单位
    • 2. 页的结构
    • 3. 页的上层结构
  • 二、页的内部结构
  • 三、InnoDB行格式
    • 1. Compact行格式
    • 2. Dynamic 和 Compressed 行格式
  • 四、区、段、碎片区和表空间
    • 1. 为什么要有区?
    • 2.为什么会有段?
    • 3. 为什么会有碎片区?
    • 4. 表空间

一、数据库的存储结构:页

我们都知道,索引信息以及数据记录都是保存在文件上的,确切说是存储在页结构中,并且索引是在存储引擎中实现的,存储引擎负责对表中数据的读取和写入工作。

1. 页是磁盘与内存交互的基本单位

  • InnoDB将数据划分为若干个页,页的大小默认为16KB。
  • 以页作为磁盘和内存之间交互的基本单位,也就是一次最少从磁盘中读取16KB的内容到内存中,也就是说,在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。

2. 页的结构

  • 多个页不在物理结构上相连,而是通过双向链表连接
  • 每个页中存储多条记录,按照主键从小到大顺序以单向链表连接

3. 页的上层结构

在这里插入图片描述

  • 页的上层结构是,一个区包含64个连续的页,大小刚好为 1MB
  • 区的上级结构是,段是数据库的分配单位
  • 段的上级结构是表空间,它是一个逻辑容器,表空间存储一个或多个段,数据库由一个或多个表空间组成。

二、页的内部结构

  • 数据页的16KB大小的存储空间被划分为七个部分,分别是 文件头(File Header)、页头(Page Header)、最大最小记录(Infimum+supremum)、用户记录(User Records)、空闲空间(Free Space)、页目录(Page Directory)和文件尾(File Tailer)。

在这里插入图片描述

三、InnoDB行格式

  • 我们平时的数据以行为单位来向表中插入数据,这些记录在磁盘上的存放方式被称为行格式或者记录格式
  • InnoDB存储引擎设计了4种不同类型的行格式,分别是 Compact、Redundant、Dynamic 和 Compressed。
  • MySQL8.0 5.7默认行格式为 Dynamic。

1. Compact行格式

  • MySQL5.1中,默认Compact行格式
    在这里插入图片描述

2. Dynamic 和 Compressed 行格式

  • 在 Compact 和 Reduntant 行格式中,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分数据,把剩余的数据分散存储在几个其他的页中进行分页存储,然后记录的真实数据处用20个字节存储指向这些页的地址,从而可以找到剩余数据所在的页。

在这里插入图片描述

四、区、段、碎片区和表空间

1. 为什么要有区?

  • B+树的每一层中的页都会形成一个双向链表,如果是以页为单位来分配存储空间的话,双向链表相邻的两个页
    之间的物理位置可能离得非常远。
  • 如果链表中相邻的两个页物理位置离得非常远,就是所谓的随机I/0,非常慢。
  • 我们应该尽量让链表中相邻的页的物理位置也相邻,也就是所谓的顺序I/0,提高速度
  • 一个区就是在物理位置上连续的64个页,在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区为单位分配,虽然这样会浪费一点空间,但可以消除很多的随机/O,功大于过。

2.为什么会有段?

  • 对于范围查询,其实是对B+树叶子节点中的记录进行顺序扫描,而如果不区分叶子节点和非叶子节点,统统把节点代表的页面放到申请到的区中的话,进行范围扫描的效果就大打折扣了。
  • 所以InnoDB对B+树的叶子节点和非叶子节点进行了区别对待,叶子节点有自己独有的区,非叶子节点也有自己独有的区。
  • 存放叶子节点的区的集合和存放非叶子节点的区的集合各自是一个段
  • 数据段即为B+树的叶子节点,索引段即为B+树的非叶子节点。
  • 段不对应表空间中某一个连续的物理区域,而是一个逻辑上的概念,由若干个零散的页面以及一些完整的区组成。

3. 为什么会有碎片区?

  • 默认情况下,一个使用InnoDB存储引擎的表只有一个聚簇索引,一个索引会生成2个段,而段是以区为单位申请存储空间的,一个区默认占用1M,所以默认情况下一个只存了几条记录的小表也分配2M的存储空间,以后每次添加一个索引都要多申请2M的存储空间,这是极大的浪费。
  • 为了考虑以完整的区为单位分配给某个段对于数据量较小的表太浪费存储空间的这种情况,InnoDB提出了一个碎片(fragment)区的概念。在一个碎片区中,并不是所有的页都是为了存储同一个段的数据而存在的,而是碎片区中的页可以用于不同的目的,比如有些页用于段A,有些页用于段B,有些页甚至哪个段都不属于。
  • 碎片区直属于表空间,并不属于任何一个段
  • 所以此后为某个段分配存储空间的策略是:
    • 在刚开始向表中插入数据的时候,段是从某个碎片区以单个页面为单位来分配存储空间的
    • 当某个段已经占用了32个碎片区页面之后,就会申请以完整的区为单位来分配存储空间

4. 表空间

  • 表空间可以看做是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中
  • 表空间是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段。
  • 表空间从管理上可以分为系统表空间、独立表空间、撤销表空间和临时表空间等。

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...