【MySQL高级篇笔记-InnoDB数据存储结构 (中) 】

news2025/1/10 19:20:10

此笔记为尚硅谷MySQL高级篇部分内容

目录

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

1、磁盘与内存交互基本单位:页

2、页结构概述

3、页的大小

4、页的上层结构

二、页的内部结构

1、分三个部分看 

2、从数据页角度看B + 树如何查询

三、InnoDB行格式(或记录格式)

四、区、段与碎片区

1、为什么要有区?

2、为什么要有段?

3、为什么要有碎片区?

4、区的分类

五、表空间

1、独立表空间

2、系统表空间


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


索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的存储引擎负责对表中数据的读取和写入工作。不同存储引擎中存放的格式一般是不同的,甚至有的存储引擎比如Memory都不用磁盘来存储数据。

由于InnoDB是MySQL的默认存储引擎,所以本章剖析InnoDB存储引擎的数据存储结构。

1、磁盘与内存交互基本单位:页

InnoDB将数据划分为若干个页,InnoDB中页的大小默认为 16KB

作为磁盘和内存之间交互的基本单位,也就是一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。也就是说,在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说,数据库管理存储空间的基本单位是页(Page),数据库I/O操作的最小单位是页。一个页中可以存储多个行记录

记录是按照行来存储的,但是数据库的读取并不以行为单位,否则一次读取(也就是一次I/O操作)只能处理一行数据,效率会非常低。

2、页结构概述

页a、页b、页c …页n这些页可以不物理结构上相连,只要通过双向链表相关联即可。每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表,每个数据页都会为存储在它里边的记录生成一个页目录,在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。

3、页的大小

不同的数据库管理系统(简称DBMS)的页大小不同。比如在MySQL的InnoDB存储引擎中,默认页的大小是16KB,可以通过下面的命令

show variables like '%innodb_page_size%';
/*
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
*/

SQL Server中页的大小为 8KB,而在oracle中用术语''’’(Block)来代表"页”,Oralce支持的块大小为2KB,4KB,8KB,16K8,32KB和64KB。

4、页的上层结构

另外在数据库中,还存在区(Extent)、段(Segment)和表空间(Tablespace)的概念。行、页、区、段、表空间的关系如下图所示:

区(Extent)是比页大一级的存储结构,在InnoDB存储引擎中,一个区会分配64个连续的页。因为InnoDB中的页大小默认是16KB,所以一个区的大小是64*16KB= 1MB。

段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在InnoDB中是连续的64个页),不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。 当创建数据表、索引的时候,就会相应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。

表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间,用户表空间撤销表空间临时表空间等。

二、页的内部结构


页如果按类型划分的话,常见的有数据页(保存B+树节点)系统页Undo页事务数据页等。数据页是我们最常使用的页。 数据页的16KB大小的存储空间被划分为七个部分,分别是文件头(File Header)、页头(Page Header)、最大最小记录(Infimum+supremum)、用户记录(User Records)、空闲空间(Free Space)、页目录(Page Directory)和文件尾(File Tailer) 。

名称占用大小说明
File Header38字节文件头,描述页的信息
Page Header56字节页头,页的状态信息
lnfimum-Supremum26字节最大和最小记录,这是两个虚拟的行记录
User Records不确定用户记录,存储行记录内容
Free Space不确定空闲记录,页中还没有被使用的空间
Page Directory不确定页目录,存储用户记录的相对位置
File Trailer8字节文件尾,校验页是否完整

1、分三个部分看 

2、从数据页角度看B + 树如何查询

一棵B+树按照节点类型可以分成两部分:

1.叶子节点,B+树最底层的节点,节点的高度为o,存储行记录。

2.非叶子节点,节点的高度大于0,存储索引键和页面指针,并不存储行记录本身。

三、InnoDB行格式(或记录格式)


我们平时的数据以行为单位来向表中插入数据,这些记录在磁盘上的存放方式也被称为行格式或者记录格式。

InnoDB存储引擎设计了4种不同类型的行格式,分别是Compact(紧密)、Redundant(冗余)、Dynamic(动态)和Compressed(压缩)行格式。

MySQL8 与 MySQL5.7的默认行格式:dynamic

 

四、区、段与碎片区


1、为什么要有区?

B+的每一层中的页都会形成一个双向链表,如果是以页为单位来分配存储空间的话,双向链表相邻的两个页之间的物理位置可能离得非常远。我们介绍B+树索引的适用场景的时候特别提到范围查询只需要定位到最左边的记录和最右边的记录,然后沿着双向链表一直扫描就可以了,而如果链表中相邻的两个页物理位置离得非常远,就是所谓的随机I/0。再一次强调,磁盘的速度和内存的速度差了好几个数量级,随机I/0是非常慢的,所以我们应该尽量让链表中相邻的页的物理位置也相邻,这样进行范围查询的时候才可以使用所谓的顺序I/0

这样利用了磁盘的预读特性

引入的概念,一个区就是在物理位置上连续64个页。因为InnoDB 中的页大小默认是16KB,所以一个区的大小是64*16KB=1MB。在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区为单位分配,甚至在表中的数据特别多的时候,可以一次性分配多个连续的区。虽然可能造成一点点空间的浪费(数据不足以填充满整个区),但是从性能角度看,可以消除很多的随机I/O,功大于过!

这里是连续的64个页, 但是具体的两个页之间还是用指针相连的。保证一大块区域连续。

2、为什么要有段?

对于范围查询,其实是对B+树叶子节点中的记录进行顺序扫描,而如果不区分叶子节点和非叶子节点,统统把节点代表的页面放到申请到的区中的话,进行范围扫描的效果就大打折扣了。所以InnoDB对B+树的叶子节点非叶子节点进行了区别对待,也就是说叶子节点有自己独有的区,非叶子节点也有自己独有的区。存放叶子节点的区的集合就算是一个段( segment),存放非叶子节点的区的集合也算是一个段。也就是说一个索引会生成2个段,一个叶子节点段,一个非叶子节点段

除了索引的叶子节点段和非叶子节点段之外,InnoDB中还有为存储一些特殊的数据而定义的段,比如回滚段。所以,常见的段有数据段索引段回滚段。数据段即为B+树的叶子节点,索引段即为B+树的非叶子节点。

在InnoDB存储引擎中,对段的管理都是由引擎自身所完成,DBA不能也没有必要对其进行控制。这从一定程度上简化了DBA对于段的管理。

段其实不对应表空间中某一个连续的物理区域,而是一个逻辑上的概念,由若干个零散的页面以及一些完整的区组成。

零散的页面,看碎片区

3、为什么要有碎片区?

默认情况下,一个使用InnoDB存储引擎的表只有一个聚簇索引,一个索引会生成2个段,而段是以区为单位申请存储空间的,一个区默认占用1M (64*16Kb=1024Kb)存储空间,所以默认情况下一个只存了几条记录的小表也需要2M的存储空间么?以后每次添加一个索引都要多申请2M的存储空间么?这对于存储记录比较少的表简直是天大的浪费。这个问题的症结在于到现在为止我们介绍的区都是非常纯粹的,也就是一个区被整个分配给某一个段,或者说区中的所有页面都是为了存储同一个段的数据而存在的,即使段的数据填不满区中所有的页面,那余下的页面也不能挪作他用。

4、区的分类

区大体上可以分为4种类型:

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

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

  • 没有剩余空间的碎片区(FULL_FRAG)︰表示碎片区中的所有页面都被使用,没有空闲页面。

  • 附属于某个段的区(FSEG):每一个索引都可以分为叶子节点段和非叶子节点段。

处于FREEFREE_FRAG以及FULL_FRAG这三种状态的区都是独立的,直属于表空间。而处于FSEG状态的区是附属于某个段的。

五、表空间


表空间可以看做是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。

表空间是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。表空间数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间 (System tablespace)、独立表空间(File-per-table tablespace)、撤销表空间(Undo Tablespace)和临时表空间(Temporary Tablespace)等。

1、独立表空间

独立表空间,即每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间(即:单表)可以在不同的数据库之间进行迁移

空间可以回收(DROPTABLE操作可自动回收表空间;其他情况,表空间不能自己回收)。如果对于统计分析或是日志表,删除大量数据后可以通过: alter table TableName engine=innodb;回收不用的空间。对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。

独立表空间结构

独立表空间由段、区、页组成。前面已经讲解过了。

真实表空间对应的文件大小

我们到数据目录里看,会发现一个新建的表对应的.ibd文件只占用了96K,才6个页面大小(MySQL5.7中),这是因为一开始表空间占用的空间很小,因为表里边都没有数据。不过别忘了这些.ibd文件是自扩展的,随着表中数据的增多,表空间对应的文件也逐渐增大。

# 查看是否独立表空间
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)

MySQL8.0中 7个页面大小。原因.idb 还存了 表结构。。。表结构.frm取消了

2、系统表空间

系统表空间的结构和独立表空间基本类似,只不过由于整个MySQL进程只有一个系统表空间,在系统表空间中会额外记录一些有关整个系统信息的页面,这部分是独立表空间中没有的。

lnnoDB数据字典

每当我们向一个表中插入一条记录的时候,MySQL校验过程如下:

先要校验一下插入语句对应的表存不存在,插入的列和表中的列是否符合,如果语法没有问题的话,还需要知道该表的聚簇索引和所有二级索引对应的根页面是哪个表空间的哪个页面,然后把记录插入对应索引的B+树中。所以说,MySQL除了保存着我们插入的用户数据之外,还需要保存许多额外的信息,比方说:

高级篇笔记PDF自取

链接:https://pan.baidu.com/s/1pVqrTwIZFoED77i-EFmw6g?pwd=3333 
提取码:3333

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/602471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试环境一键发布

背景 目前公司项目发布测试环境不够自动化,每次需要手动打包并且手动更新,影响开发效率 流程图 而且因为是本地手动发布,容易失误造成一些不必要的麻烦: 远端代码有更新,忘记拉取代码 快速发布,本地代码…

Redis7实战加面试题-高阶篇(Redis为什么快?高性能设计之epoll和IO多路复用深度解析)

多路复用要解决的问题 并发多客户端连接,在多路复用之前最简单和典型的方案:同步阻塞网络IO模型 这种模式的特点就是用一个进程来处理一个网络连接(一个用户请求),比如一段典型的示例代码如下。 直接调用 recv 函数从一个 socket 上读取数据…

Nginx:Nginx优化与防盗链

Nginx:Nginx优化与防盗链 一、配置Nginx隐藏版本号二、修改Nginx用户与组三、配置Nginx网页缓存时间3.1 修改配置文件3.2 页面缓存验证 四、配置Nginx实现连接超时五、更改Nginx运行进程数六 、配置Nginx实现网页压缩功能七、配置Nginx实现防盗链 一、配置Nginx隐藏…

[数据集][目标检测]目标检测数据集蜜蜂4073张1类别VOC格式

出品方:未来自主研究中心(FIRC) 数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):7398 标注数量(xml文件个数):7398 标注类别数&#xff…

如何利用宝塔面板快速搭建Wordpress网站?

本章教程,主要介绍一下,如何利用宝塔面板快速搭建Wordpress网站。 目录 一、 前置条件 二、 打开宝塔面板 三、解析域名 四、安装界面 五、主题安装 六、网站预览 一、 前置条件 需要准备一台Linux服务器,系统版本使用centos 7.X。 使用…

这两个PPT素材网站很多大佬都在用

01 OfficePLUS是一款基于Microsoft Office的专业辅助工具,能够为用户提供更加高效、便捷的办公体验。该工具针对多个版本的Office软件进行优化和定制,提供了丰富的功能和实用的设计资源,如PPT模板、Word模板、Excel模板等。 OfficePLUS的主…

除了ChatGPT,还有哪些好用的AI工具?(建议收藏)

目前市面上的AI工具非常多,本文对他们进行了汇总整理,大家可以按需下载或者使用哦~ 一、AI对话聊天工具 1、New Bing(AI对话搜索) https://cn.bing.com 有点像ChatGPT版的必应,可以帮你搜索问题、回答问题、写文案、写…

简单分析jsjiami.v6加密逻辑

代码案例: var _0xodRjsjiami.com.v6,_0xodR_function(){return[‮_0xodR],_0x4311[_0xodR,TMOw51jPALDkw,w6LDqcOhw7PCqQ,I8OkP0zDs8KF,fyjCv8OB,CMOdEk5b,OnthccOZHXXDoA,UnDCrcKvw61VAsKNw7TCoRN8wpkhFVzCgA40woV6wrTCtMOXbXo,CMOiwohCXsKhw4PDq8KKw5MbPMOnWVjC…

基于LayUI+Servlet的权限管理系统的设计

权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或操作不当引发的风险问题,如操作错误,隐私数据泄露等问题。本系统基于JSPServletJDBCLayUI的技术&#xff…

Java并发体系-第三阶段-JUC并发包-[2]-CompleableFuture,SynchronousQueue

Phaser工具(有时间就了解一下,下面还有队列) 简介 java7中引入了一种新的可重复使用的同步屏障,称为移相器Phaser。Phaser拥有与CyclicBarrier和CountDownLatch类似的功能. 但是这个类提供了更加灵活的应用。CountDownLatch和CyclicBarrier都是只适用于固定数量的…

(5)NUC980先来点个灯如何设置开启自启动

嵌入式Linux开机启动过程: 可以分为以下几个步骤: CPU复位:开机时,CPU会执行复位操作,将内存的内容清空,寄存器的初始值复位。 ROM启动:CPU会从ROM中读取启动程序,将其加载到内存中…

【阅读笔记】时间序列之TPA-LSTM(含Pytorch代码实现)

本文作为自己阅读论文后的总结和思考,不涉及论文翻译和模型解读,适合大家阅读完论文后交流想法,关于论文翻译可以查看参考文献。论文地址:https://arxiv.org/abs/1809.04206 TPA-LSTM 一. 全文总结二. 研究方法三. 结论四. 创新点…

C++ 学习 ::【基础篇:13】:C++ 类的基本成员函数:类类型成员的初始化与构造函数问题

本系列 C 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C的三大特性等&#…

科技云报道:数字化时代,企业终端安全防护该“上新”了!

科技云报道原创。 随着云计算、大数据、物联网等创新技术的加速落地,企业原有的网络边界被打破,各种终端设备如:笔记本电脑、台式机、平板电脑、智能手机、物联网终端等成为了新的安全边界。 在此背景下,想确保企业高效办公的灵活…

罗德与施瓦茨FSWP26相位噪声分析仪

罗德与施瓦茨FSWP26 相位噪声分析仪和VCO测试仪 FSWP相位噪声分析仪和VCO测试仪结合极低噪声内源和互相关技术,实现了相位噪声测量的超高灵敏度。因此,即便测量高度稳定的源 (例如在雷达应用中的源) 也只需几秒钟。脉冲信号测量、附加相位噪声 (包括脉冲…

【敲敲云】免费的零代码产品 — 应用用户角色与权限

之前的文章我们介绍了应用创建与设置,应用的使用离不开权限设置,毕竟不是每个人都可以查看所有的工作表,下面我们再来看一下应用的角色与权限。 一、应用用户 应用用户: 结合应用角色,可设置哪些用户可以访问哪些应用或…

Numpy---ndarray的特点、效率

1. Numpy Numpy(Numerical Python)是一个开源的 Python 科学计算库,用于快速处理任意维度的数组。 Numpy 支持常见的数组和矩阵操作。对于同样的数值计算任务,使用 Numpy 比直接使用 Python 要简洁的多。 Numpy 使用 ndarray 对…

Redis五大数据结构的底层实现

一)String类型:可以使用object encoding name就可以查看字符串的编码 SDS,flags的值不同,那么len和alloc所表示的值的数据范围也不同,所以flags的只是为了标识SDS头的总大小; alloc和len刚开始进行申请内存空间的时候都是相同的 S…

Vue.js 中的父子组件通信方式

Vue.js 中的父子组件通信方式 在 Vue.js 中,组件是构建应用程序的基本单元。当我们在应用程序中使用组件时,组件之间的通信是非常重要的。在 Vue.js 中,父子组件通信是最常见的组件通信方式之一。在本文中,我们将讨论 Vue.js 中的…

原神3.2服务端PC端架设教程

安装教程 安装 MongoDB,不会安装建议使用宝塔面板 sudo apt updatesudo apt install mongodb-orgsudo systemctl enable --now mongod 直接启动.如果失败看看数据库启动了没有.端口一致 ./start.sh 安装配置JDK17 双击 OpenJDK17U-jdk_x64_windows_hotspot_1…