MySQL索引的实现——数据页结构(InnoDB引擎)

         建议三篇一起看:

  1. MySQL索引的实现——行结构(InnoDB引擎)   链接:https://blog.csdn.net/qq_52074153/article/details/128500644
  2. MySQL索引的实现——数据页结构(InnoDB引擎)   链接:                        https://blog.csdn.net/qq_52074153/article/details/128500644
  3. MySQL索引的实现——B+树构造(InnoDB引擎)   链接:                                                      MySQL索引的实现——B+树的构造(InnoDB引擎)_我吃那桌小孩的博客-CSDN博客

     首先,介绍一下页的概念。页是InnoDB管理存储空间的基本单位,以页作为磁盘和内存之间交互的基本单位。InnoDB中页的大小一般为16KB,也就是说,一般情况下,一次最少从磁盘读取16KB的内容到内存中。

        InnoDB为了不同目的设计的多种不同类型的页,本篇主要讲的是索引(index)页。

索引页组成部分如下图和下表所示:

MySQL索引的实现——数据页结构(InnoDB引擎)_第1张图片

名称 中文名 占用空间大小 简单描述
File Header 文件头 38字节 页的一些通用信息
Page Header 页面头 56字节 数据页专有的一些信息
Infimum+Supremum 页面中最小记录和最大记录 26字节 两个虚拟记录
User Recoder 用户记录 不确定 用户存储的记录内容
Free Space 空闲空间 不确定 页中尚未使用的空间
Page Directory 页目录 不确定 页中某些记录的相对位置
File Trailer 文件尾部 8字节 检验页是否完整

1.Page Directory(页目录)

        在介绍行格式中,我们知道了记录在页中是按主键值由小到大串联成应该单向链表,这时我们想查找页中的某条记录,这时如果要查询就不能直接链表查询,这样速度非常慢。所以/innoDB引擎设计了一个目录,通过目录来查找,制作过程如下:

1.将所有正常的记录(包括Infimum 和Supremum记录,但不包括已经移珠到地麦要来的记录)划分为几个组。
2.每个组的最后一条记录)也就是组内最大的那条记录)相当于“带头大哥”。圣大其全公运录相当于“小弟”。“带头大哥”记录的头信息中的n_owned
3. 将每个组中最后一条记录在页面中的地址偏移量(就是该记录的真实数据与页面中第0个字节之间的距离)单独提取出来,按顺序存储到靠近页尾部的地方。这个地方就是Page Directory (页目录)。 页目录中的这些地址偏移量称为槽(Slot).每个槽占用2字节。页目录就是由多个槽组成的。

2.File Header(文件头部)

       现在介绍的File Header通用于各种类型的页,描述了通用于各种页的信息,由下表内容组成:

名称 占用空间大小 描述
FIL_PAGE_SPACE_OR_CHKSUM 4字节 页的校验和
FIL_PAGE_OFFSET 4字节 页号
FIL_PAGE_PREV 4字节 上一页页号
FIL_PAGE_NEXT 4字节 下一页页号
FIL_PAGE_LSN 8字节 页面最后被修改的对应的日志序列号值
FIL_PAGE_TYPE 2字节 该页类型
FIL_PAGE_FILE_FLUSH_LSN 8字节 文件刷新到了哪个LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4字节 页属于哪个表空间

         FIL_ PAGE PREV和FIL PAGE NEXT:前文强调过,InnoDB 是以页为单位存放数据的,有时在存放某种类型的数据时,占用的空间非常大(比如一张表中可以有成千上万条记录)。InnoDB可能无法一次性为这么多数据分配一个非常大的存储空间,而如果分散到多个不连续的页中进行存储,则需要把这些页关联起来,FIL PAGE PREV和FIL PAGE NEXT就分别代表本数据页的上一个页和下一个页的页号。这样通过建立一个双向链表就把许许多多的页串联起来了,而无须这些页在物理上真正连着。需要注意的是,并不是所有类型的页都有上一个页和下一个页的属性,所以存储记录的数据页可以组成一个双向链表。如下图:

MySQL索引的实现——数据页结构(InnoDB引擎)_第2张图片

你可能感兴趣的:(mysql,数据库,sql)