MYSQL08_页的概述、内部结构、文件头、文件尾、最大最小记录、页目录、区段表

文章目录

  • ①. 页的概述、大小
  • ②. 页的内部结构
  • ③. 第一部分 - 文件头
  • ④. 第一部分 - 文件尾
  • ⑤. 第二部分 - 空闲、用户记录、最大最小
  • ⑥. 第三部分 - 页目录
  • ⑦. 第三部分 - 页面头部
  • ⑧. 从数据页角度看B+树
  • ⑨. 区、段和表、碎片区

①. 页的概述、大小

  • ①. 数据库的存储结构:页
  1. 索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切来说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的存储引擎负责对表中数据的读取和写入工作。不同的存储引擎中存放的格式一般是不同的,甚至有的存储引擎Memory都不用磁盘来存储数据
  2. 由于InnoDB是MySQL的默认存储引擎,所以本章节讲解InnoDB存储引擎的数据存储结构
  • ②. 磁盘与内存交互的基本单位:页
  1. InnoDB将数据划分为若干个页,InnoDB中页的默认大小为16KB
  2. 以页作为磁盘和内存之间交互的基本单位,也就是一次最少从磁盘中读取16KB的内容到内存中,一次最少把16KB的内容刷新到磁盘中
  3. 在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说数据库管理存储空间的基本单位是页,数据库I/O操作的最小单位也是页。一个页中可以存储多个行记录
    注意:记录是按照行来储存的,但是数据库的读取并不以行为单位,否则一次读取(也就是一次I/O操作),只能处理一行数据,效率会非常的低
  • ③. 页结构概述
  1. 页a、页b、页c,这些页可以不在物理结构上相连,只要通过双向链表相关联即可
  2. 每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表,每个数据页都会为存储在它里边的记录生成一个页目录
  3. 在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽
    在这里插入图片描述
  • ④. 页的大小
    不同数据库管理系统的页大小不同,MySQL的InnoDB存储引擎中,默认的页大小是16KB
    SQL Server中页的大小为8kb,而在Oracle中我们用术语"块"来代表页,Oracke支持的块大小为2kb、4kb、8kb、16kb、32kb、64kb
mysql> show variables like '%innodb_page_size%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
  • ⑤. 页的上层结构,在数据库中还存在着区、段、和表空间的概念
  1. 区(Extent)是比页大一级的存储结构,在InnoDB存储引擎中,一个区会分配64个连续的页。因为InnoDB中的页大小默认是16KB,所以一个区的大小是64 * 16KB = 1MB
  2. 段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在InnoDB中是连续的64个页),不过在段中不要求区与区之间是相邻的。段是数据库中分配单位,不同类型数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会响应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段
  3. 表空间(Tablespace)是一个逻辑容器,表空间储存的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间
    在这里插入图片描述

②. 页的内部结构

  • ①. 页按照类型划分,常见的有数据页(保存B+树节点)、系统页、Undo页和事务数据页等。数据页是我们最常使用的页,页结构示意图如下:
    在这里插入图片描述
  • ②. 数据页16KB大小的存储空间被划分为七个部分,分别是文件头、页头、最大最小记录、用户记录、空闲空间、页目录和文件尾,如下图所示

在这里插入图片描述

③. 第一部分 - 文件头

  • ①. File Header:描述各种页的通用信息。比如页的编号、其上一页、下一页是谁等、大小为38字节

  • ②. File Header文件头部具体构成
    在这里插入图片描述

  • ③. FIL_PAGE_OFFSET:每一个页都有一个单独的页号,就跟你的身份证号码一样,InnoDB通过页号可以唯一定位一个页

  • ④. FIL_PAGE_TYPE:代表当前页的类型
    在这里插入图片描述

  • ⑤. FIL_PAGE_PREV和FIL_PAGE_NEXT
    InnoDB都是以页为单位存放数据的,如果数据分散到多个不连续的页中存储的话需要把这些页关联起来,FIL_PAGE_PREV和FIL_PAGE_NEXT就分别代表本页的上一个和下一个页的页号。这样通过建立一个双向链表把许许多多的页就都串联起来了,保证这些页之间不需要是物理上的连续,而是逻辑上的连续
    在这里插入图片描述

  • ⑥. FIL_PAGE_SPACE_OR_CHKSUM:代表当前页面的校验和checksum

  1. 文件头部和文件尾部都有属性:FIL_PAGE_SPACE_OR_CHKSUM
  2. 什么是校验和?对于一个很长的字节串来说,我们会通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和
  3. 在比较两个很长的字节串之前,先比较这两个长字节串的校验和,如果校验和都不一样,则两个长字节串肯定是不同的,所以省去了直接比较两个比较长的字节串的时间损耗
  • ⑦. 校验和的作用
  1. InnoDB存储引擎以页为单位把数据加载到内存中处理,如果该页中的数据在内存中被修改了,那么在修改后的某个时间需要把数据同步到磁盘中。但是在同步了一半的时候断电了,造成了该页传输的不完整
  2. 为了检测一个页是否完整也就是在同步的时候有没有发生只同步一半的尴尬情况,这时可以通过文件尾的校验和checksum值与文件头的校验和做比对,如果两个值不相等则证明页的传输有问题,需要重新进行传输,否则认为页的传输已经完成
  • ⑧. 校验和举例子
  1. 每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的
  2. 如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错。这里,校验方式就是采用 Hash 算法进行校验
  • ⑨. FIL_PAGE_LSN:页面被最后修改时对应的日志序列位置英文名是:Log Sequence Number

④. 第一部分 - 文件尾

  • ①. 大小8字节
  1. 前4个字节代表页的校验和:这个部分是和File Header中的校验和相对应的
  2. 后4个字节代表页面被最后修改时对应的日志序列位置LSN:这个部分也是为了校验页的完整性的,如果首部和尾部的LSN值校验不成功的话,就说明同步过程出现了问题
  • ②. 文件头部和文件尾部都有属性:FIL_PAGE_SPACE_OR_CHKSUM

⑤. 第二部分 - 空闲、用户记录、最大最小

  • ①. 页的主要作用是存储记录,所以 “最大和最小记录” 和 “用户记录” 部分占了页结构的主要空间
    在这里插入图片描述
  • ②. Free Space (空闲空间)
    我们自己存储的记录会按照指定的行格式存储到User Records部分。但是在一开始生成页的时候,其实并没有User Records这个部分,每当我们插入一条记录,都会从Free Space部分,也就是尚未使用的存储空间中申请一个记录大小的空间划分到User Records部分,当Free Space部分的空间全部被User Records部分替代掉之后,也就意味着这个页使用完了,如果还有新的记录插入的话,就需要去申请新的页了

在这里插入图片描述

  • ③. User Records中的这些记录按照指定的行格式一条一条摆在User Records部分,相互之间形成单链表

  • ④. Infimum + Supremum(最小最大记录)
    InnoDB规定的最小记录与最大记录这两条记录的构造十分简单,都是由5字节大小的记录头信息和8字节大小的一个固定的部分组成的,如图所示
    在这里插入图片描述
    在这里插入图片描述

⑥. 第三部分 - 页目录

  • ①. 为什么需要页目录?
    在页中,记录是以单向链表的形式进行存储的。单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索。因此在页结构中专门设计了页目录这个模块,专门给记录做一个目录,通过二分查找法的方式进行检索,提升效率

  • ②. 需求:根据主键值查找页中的某条记录,如何实现快速查找呢?

SELECT * FROM page_demo WHERE c1 = 3;

方式1:顺序查找
从Infimum记录(最小记录)开始,沿着链表一直往后找,总有一天会找到(或者找不到),在找的时候还能投机取巧,因为链表中各个记录的值是按照从小到大顺序排列的,所以当链表的某个节点代表的记录的主键值大于你想要查找的主键值时,你就可以停止查找了,因为该节点后边的节点的主键值依次递增(如果一个页中存储了非常多的记录,这么查找性能很差)
方式2:使用页目录,二分法查找

  1. 将所有的记录分成几个组,这些记录包括最小记录和最大记录,但不包括标记为“已删除”的记录。
  2. 第1组,也就是最小记录所在的分组只有1个记录;
    最后一组,就是最大记录所在的分组,会有1-8条记录;
    其余的组记录数量在4-8条之间
    这样做的好处是,除了第1组(最小记录所在组)以外,其余组的记录数会尽量平分
  3. 在每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为n_owned字段。
  4. 页目录用来存储每组最后一条记录的地址偏移量,这些地址偏移量会按照先后顺序存储起来,每组的地址偏移量也被称之为槽(slot),每个槽相当于指针指向了不同组的最后一个记录
    在这里插入图片描述
  • ③. 现在的page_demo表中正常的记录共有6条,InnoDB会把它们分成两组,第一组中只有一个最小记录,第二组中是剩余的5条记录。如下图
  1. 现在页目录部分中有两个槽,也就意味着我们的记录被分成了两个组,槽1中的值是112,代表最大记录的地址偏移量(就是从页面的0字节开始数,数112个字节);槽0中的值是99,代表最小记录的地址偏移量
  2. 注意最小和最大记录的头信息中的n_owned属性
    最小记录的n_owned值为1,这就代表着以最小记录结尾的这个分组中只有1条记录,也就是最小记录本身
    最大记录的n_owned值为5,这就代表着以最大记录结尾的这个分组中只有5条记录,包括最大记录本身还有我们自己插入的4条记录

在这里插入图片描述
在这里插入图片描述

  • ④. 在一个数据页中查找指定主键值的记录的过程分为两步(非常重要)
  1. 通过二分法确定该记录所在的槽,并找到该槽所在分组中主键值最小的那条记录
  2. 通过记录的next_record属性遍历该槽所在的组中的各个记录

⑦. 第三部分 - 页面头部

  • ①. 为了能得到一个数据页中存储的记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么,页目录中存储了多少个槽等等,特意在页中定义了一个叫Page Header的部分,这个部分占用固定的56个字节,专门存储各种状态信息
    在这里插入图片描述

  • ②. PAGE_DIRECTION:假如新插入的一条记录的主键值比上一条记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边。用来表示最后一条记录插入方向的状态就PAGE_DIRECTION

  • ③. PAGE_N_DIRECTION:假设连续几次插入新记录的方向都是一致的,InnoDB会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION这个状态表示。当然,如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计

⑧. 从数据页角度看B+树

  • ①. 一颗B+树按照节点类型可以分成两部分
  1. 叶子节点,B+树最底层的节点,节点的高度为0,储存行记录
  2. 非叶子节点,节点的高度大于0,储存索引键和页面指针,并不储存行记录本身
    在这里插入图片描述
  • ②. B+树是如何进行记录检索的呢
    从B+树的跟几点开始,逐层检索,在哪个目录项里面,进行定位到具体的页,将数据页加载到内存中,页目录中的槽(slot)采用二分查找的方式找到一个粗略的记录分组,找到最小的那条记录,通过next_record遍历查找记录

  • ③. 普通索引和唯一索引在查询效率上有什么不同?
    唯一索引就是在普通索引上增加了约束性,也就是关键字唯一,找到了关键字就停止检索。而普通索引,可能会存在用户记录中的关键字相同的情况,根据页结构的原理,当我们读取一条记录的时候,不是单独将这条记录从磁盘中读出去,而是将这个记录所在的页加载到内存中进行读取。InnoDB储存引擎的页大小为16KB,在一个页中可能存储着上千条记录,因此在普通索引的字段上进行查找页就是在内存中多几次"判断下一条记录"的操作,对于CPU来说,这些操作所消耗的时间是可以忽略不计的。所以对一个索引字段进行检索,采用普通索引还是唯一索引在检索效率上基本上没差别

⑨. 区、段和表、碎片区

  • ①. 为什么要有区?
  1. B+树的每一层中的页都会形成一个双向链表,如果是以页为单位来分配存储空间的话,双向链表相邻的两个页之间的物理位置可能离的非常远,如果需要范围查询的话只需要定位最左边和最右边的记录,沿着双向链表一直扫描即可,而如果两个页之间的物理位置隔得非常远,就是所谓的随机I/O,这是非常慢的,所以应该尽量让链表中相邻页的物理位置页相邻,这样进行范围查询时才可以使用所谓的顺序I/O
  2. 这就引入了的概念,一个区就是在物理位置上连续的64个页,因为InnoDB的页大小默认是16KB,所以一个区的大小是1MB。在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区为单位分配,甚至在表中数据特别多的时候,可以一次性分配多个连续的区。虽然可能造成一点点空间的浪费,但是从性能角度看,可以消除很多随机I/O

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云原生:10分钟了解一下Kubernetes架构

Kubernetes,作为当今容器编排技术的事实标准,以其强大的功能和灵活的架构设计,在全球范围内得到了广泛的应用和认可。本文将深入简出地探讨Kubernetes的核心架构,帮助大家了解Kubernetes,为今后的高效的学习打下良好的…

计算机网络 Cisco虚拟局域网划分

一、实验内容 1、分别把交换机命名为SWA、SWB 2、划分虚拟局域网 valn ,并将端口静态划分到 vlan 中 划分vlan 方法一:在全局模式下划分vlan,在SWA交换机上创建三个vlan,分别为vlan2,vlan3,vlan4。 方…

1.初识Docker与容器

初识Docker与容器 文章目录 初识Docker与容器1、什么是DockerDocker架构 2、为什么使用DockerDocker容器虚拟化的好处Docker与虚拟机比较Docker为什么快 1、什么是Docker Docker是基于Go语言实现的开源容器项目。Docker是为解决了运行环境和配置问题的软件容器,方便…

24.4.11-13C语言学习笔记|函数、部分结构体【未完待续】

巴拉巴拉~~~哭死,学习啊啊啊啊,学校课好多,只能半夜学了 4.2函数名--特殊的地址: void fun(int a){ int aa1; printf("%d",a); return a; } 指针函数?? void …

(五)C++自制植物大战僵尸游戏LoadingScene的实现讲解

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/xjvbb 一、类介绍 游戏启动后就会立即切换到游戏加载场景中。只有游戏资源文件加载完成后,才能进入游戏。Loadingscene类继承Cocos2d-x中的Scene父类,表明Loadingscene是一个场景类。切换到Loadi…

Mathorcup 甲骨文识别

本资源主要包含第2-4问,第一问直接使用传统图像处理即可,需要有很多步骤,这一步大家自己写就行。 2 第2问,甲骨文识别 2.1 先处理源文件 原文件有jpg和json文件,都在一个文件夹下,需要对json文件进行处理…

大数据存储解决方案和处理流程——解读大数据架构(四)

文章目录 前言数据存储解决方案数据集市运营数据存储(Operational Data Store)数据中心 数据处理数据虚拟化和数据联合虚拟化作为 ETL 或数据移动的替代品数据目录数据市场 前言 在数字时代,数据已成为公司的命脉。但是,仅仅拥有…

读《AI营销画布》品牌企业成长的逻辑(四)

前言 曾几何时,为了销售和品牌这两个扯的一世不可开交,也因为这个在企业里,形成了二个主张派,一派是以为销售为目标;一派是以品牌为目标。最后,,,,也就形成了不同的意见&…

c# .net 香橙派 Orangepi GPIO高低电平、上升沿触发\下降沿触发 监听回调方法

c# .net 香橙派GPIO高低电平、上升沿触发\下降沿触发 监听回调方法 通过gpio readall 查看 gpio编码 这里用orangepi zero3 ,gpio= 70为例 当gpio 70 输入高电平时,触发回调 c# .net 代码 方法1: Nuget 包 System.Device.Gpio ,微软官方库对香橙派支持越来越好了,用得…

学习JavaEE的日子 Day38 网络编程

Day38 网络编程(了解即可) 1. 计算机网络 2. 网络编程 实现多台计算机之间实现数据的共享和传递,网络应用程序主要组成为:网络编程IO流多线程 3. 网络模型 两台计算机之间的通信是根据什么规则来走的(OSI & TCP/IP) 此处简单了解该模型就行《TCP/IP…

Windows瘦客户机系统默认英文?一招改成中文界面

前言 最近发现有很多小伙伴给电脑安装了Windows瘦客户机系统,但开机之后发现系统是英文的,看都看不懂。 今天就给小伙伴们带来更改Windows Thin系统语言的办法。 首先,咱们都知道,更改系统显示语言基本上都是在系统设置或者控制…

Java——类和对象

目录 一.类定义和使用 1.简单认识类 2.类的定义格式 3.注意事项 二.课堂练习 1.定义一个狗类 2.定义一个学生类 3.注意事项: 三.类的实例化 1.什么是实例化 2.注意事项 3.类和对象的说明 四.this引用 1.为什么要有this引用 2.什么是this引用 五.对…

第16章 数据管理组织与角色期望知识点梳理

第16章 数据管理组织与角色期望知识点梳理(附带页码) ◼ 数据管理和数据治理组织需要足够灵活,才能在不断发展的环境中有效地工作。意识、所有权和问责制度是激励和吸引人们参加数据管理积极性、政策和流程的关键。P432 ◼ 如何了解组织的企…

【Docker】docker原理及使用-1

Docker目录 1️⃣概念2️⃣使用容器的好处2️⃣docker和普通软件启动方式的区别2️⃣docker和传统虚拟机的区别 1️⃣下载安装2️⃣安装步骤 1️⃣必须要掌握的核心概念1️⃣命令2️⃣例子2️⃣练习题目2️⃣进入一下python环境(简洁) 1️⃣解释一下 redis1️⃣docker底层隔离机…

AI大模型探索之路-应用篇12:AI大模型应用之向量数据库选型

目录 前言 一、什么是向量数据库? 二、向量数据库的应用场景 1. 图像检索 2. 推荐系统 3. 自然语言处理 三、向量数据库在AI大模型中的应用 1. 训练数据的索引和检索 2. 特征存储和管理 3. 模型中间结果的存储 4. 长上下文的记录和检索 5. 本地知识库的构…

基于springboot实现购物推荐网站系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现购物推荐网站系统演示 摘要 随着信息互联网购物的飞速发展,一般企业都去创建属于自己的电商平台以及购物管理系统。本文介绍了东大每日推购物推荐网站的开发全过程。通过分析企业对于东大每日推购物推荐网站的需求,创建了一个计算机管…

Python求利率

要求 编写程序计算在给定利率、指定年数的情况下投资的未来值。这个计算公式如下。 使用文本域输入投资额、年份和利率。当用户单击“calculate”按钮时,在文本域中显示未来的投资值,如图所示。 代码实现 import tkinter as tkdef calculate():amou…

Spring Batch

Spring是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及W…

使用Python爬虫代理IP快速增加博客阅读量

目录 前言 二、Python爬虫代理IP技术简介 1.什么是爬虫? 2.什么是代理IP? 3.为什么使用代理IP? 三、使用Python爬虫代理IP增加博客阅读量的步骤 1.获取代理IP地址 2.模拟多次访问 3.定时任务 四、注意事项 五、总结 前言 随着互联…

金融机构与金融市场监管

金融机构与金融市场监管 中国的金融监管机构银行业监管的必要性银行业监管的基本目标银行业监管的基本内容商业银行的设立审批制度银行业日常监督管理流动性要求资产质量监管合理的内部控制制度风险集中和风险暴漏的监管银行资本风险资本的计算资本充足率的计算 中国的金融监管…