当前位置: 首页 > news >正文

从根上理解 mysql -数据在表中是怎么存储的

之前说了,一行数据是怎么存储的 以及数据在页中是怎么存储了,现在来看看,数据在表中的是怎么存储的

从根上理解 mysql -一行数据是怎么存储的
从根上理解 mysql -数据在页中是怎么存储的

在页的数据结构中 FIL_PAGE_PREV 、FIL_PAGE_NEXT 表示上一个和下一个页号,形成双向链表结构。但是,如果页面是随机分配的话,查询下一页数据的时候就会变成随机IO,随机IO效率是很低的。所以,有了的概念。

区(extent):连续64个页组成一个区 1MB
:每256个区划分为一个组,每个组的前几个页面都是固定的(这里很重要),用于存储组和表的通用信息。

先想想为什么要有组的概念???

在这里插入图片描述每个组的前几个页面都是固定的每个组的前几个页面都是固定的
ok,引入区的概念是为了转随机IO为顺序IO,但是B+树中真正存储数据的是叶子结点,如果把所有节点都放在一起,那么在进行范围查询的时候,也是随机IO。所以,有了的概念

叶子节点和非叶子节点的是分开存放的。存放叶子节点的区的集合就算是一个段,非叶子节点的区集合算另外一个段。即,一个索引会有两个段,一个叶子节点段,一个非叶子节点段。

问题又来了?

一个区默认1M, 一个索引两个段,哪怕一个段中只有一个区,一个索引也是至少2M空间,这未免有点浪费吧。所以有个碎片区的概念 (fragment)

所以,区按照所属,又分为

  • Free 空闲的区
  • Free_Frag 有剩余空间的碎片区
  • Full_Frag 没有剩余空间的碎片区
  • Fseg 附属某个段的区

即,一开始为某个段分配页的时候,从碎片化区中分配,当段中已经占据32个零散的页后,就直接申请区进行存储。

上面 Free、Free_Frag、Full_Frag 属于表空间,且每种属性都对应链表。

为了区分区属于哪个段,段中的区也有对应的链表管理

  • FREE链表 同一个段中完全空闲的区
  • NOT_FULL链表 同一个段中仍有空闲的区
  • FULL链表 同一个段中没有空闲的区

所以,每一个段都会对应三个上述链表。即一个索引2个段,每个段3个列表。

上面所说的链表是怎么维护的???

实际上,每个区都会维护一个数据结构:XDES Entry
在这里插图片描述

  • Segment ID 该区所属的段Id,当然只针对Fseg,表直属的区该字段无意义
  • List Node 主要靠这个将XDES Entry 链接成链表
  • State 区的类型 (上面区分的 - Free、Free_Frag、Full_Frag、Fseg )
  • Page State Bitmap 16Kb 即128B。128/2 =64 正好对应一个区的64个页,用于表示区中的页是否空闲。

所以,综上:

  1. 为了避免页的随机访问,有个区的概念(64个连续的页)
  2. 区分为:a. 表空间的直属区 b.所属段的区
  3. 每个索引都对应两个段(叶子节点和非叶子节点)
  4. 表空间的直属的三个区对应三个链表,所属段的区中也对应三个链表,链表是通过XDES Entry数据结构连接的
  5. 段:碎片区中的32个离散的页+若干个区
  6. 统计一个表中共有几个链表:3+ n_index * 2 * 3。例:若一个表中有两个索引,那么一共对应15个链表(表空间的3个链表+ 2(索引个数)*2(每个索引段的个数)*3(每个段链表的个数))

段的结构(段是逻辑概念 非物理概念)

在这里插入图片描述

ok,消化完,继续。

消化完,问题又来了

  1. 每个区对应的XDES Entry在哪里
  2. 直属表空间的 三个链表在哪里(Free、Free_Frag、Full_Frag)
  3. 每个段对应的INODE Entry存储在哪里

所以,六丁六甲从不吃素…

在上面说到组的时候(256个区定义为一个组)说到,每个组的前几个页面的类型都是固定的,往上翻翻吧。

第一组的第一页 FSP_HDR类型

在这里插入图片描述
File Header和File Trailer 是所有类型页面通用的,不再强调了。另外的几个部分中,Empty Space是尚未使用的空间,不用管。重点来看看File Space Header和XDES Entry这两个部分。

File Space Header部分

在这里插入图片描述

  • Space ID 表空间
  • Not Used 未使用
  • Size 表的页面数
  • List Base Node for FREE List、List Base Node for FREE_FRAG List、List Base Node for FULL_FRAG List 表空间的直属三个列表的基节点。so,表级别的区链表在第一组的第一个页面中
  • FRAG_N_USED 这个字段表明在FREE_FRAG链表中已经使用的页面数量。
  • FREE Limit 表示在这之前的页面的区均已经被初始化了,可以用了。后面的均未被初始化
  • Next Unused Segment ID 下一个段的ID 用户给新建的段 分配id
  • Space Flags 其他的布尔类型的属性
  • List Base Node for SEG_INODES_FULL List和List Base Node for SEG_INODES_FREE List
XDES Entry部分

每个区都对应一个XDES Entry结构,占40b,但是一个页面就16kb。所以一个页面能放的XDES Entry是有限的,所以,才有了组的概念(不分组 放不下啊)。

第一组的第二页 IBUF_BITMAP类型

记录了一些有关Change Buffer的东西。先不论述,我怕乱了。

第一组的第三页 INODE类型

一个索引对应两个段,还有一些特殊含义的别的段。每个段对应INODE Entry结构。INODE类型的页面就是管理段的。

在这里插入图片描述
同理,代表段的INODE Entry结构占用192个字节,一页能存储85个这样的结构,但是如果表中的数据超过85个段,就需要用别的INODE类型的页面来存储。所以就有了List Node for INODE Page List(存储上一个INODE页面和下一个INODE页面的指针)。

List Node for INODE Page List 有两种类型:

  1. SEG_INODES_FULL链表:该链表中的INODE类型的页面中已经没有空闲空间来存储额外的INODE Entry结构了。
  2. SEG_INODES_FREE链表:该链表中的INODE类型的页面中还有空闲空间来存储额外的INODE Entry结构了

看到这里熟悉了吧,这两个链表的头节点就在File Space Header中。

非第一组的第一页 XDES类型

在这里插入图片描述
这个就很简单了,基本上和第一组的第一页 FSP_HDR类型类似,只是因为第一组的第一页需要存储表的信息。

行了,今天就到这里吧。


http://www.mrgr.cn/news/79934.html

相关文章:

  • AI智算-k8s部署大语言模型管理工具Ollama
  • Golang学习笔记_05——延迟调用
  • 【安全月报】| 9月区块链安全事件有所下降,因黑客攻击等损失金额达1.2亿美元
  • scroll-view 实现滑动显示,确保超出正常显示,小程序app,h5兼容
  • HNSW 分布式构建实践
  • CSS学习记录11
  • location重定向和nginx代理
  • MySQL-练习-数据介绍
  • Linux 权限及管理
  • Java 实现给pdf文件指定位置盖章功能
  • ARM学习(35)单元测试框架以及MinGW GCC覆盖率报告
  • 特征交叉-CAN学习笔记代码解读
  • java抽奖系统登录下(四)
  • R学习——数据框
  • Leetcode数学部分笔记
  • [大数据]Hudi编译集成
  • 与 Cursor AI 对话编程:2小时开发报修维修微信小程序
  • 搭建Tomcat(一)---SocketServerSocket
  • Python 单例模式工厂模式和classmethod装饰器
  • vue3+vite接入iconify,支持离线
  • Docker的初识
  • IP研究 | 大数据洞察黄油小熊的爆火之路
  • 【数字花园】个人知识库网站搭建:②本地部署数字花园
  • 原生微信小程序使用原子化tailwindcss
  • 【数据结构——查找】顺序查找(头歌实践教学平台习题)【合集】
  • Ultra-Fast-Lane-Detection复现、部署及训练