Mysql学习记录-InnoDB存储的结构


 数据在不同存储引擎中存放的格式是不同的InooDb最常用

InnoDB行格式

 以记录为单位往表中插入数据,在磁盘上存放的方式称为行格式目前有四种,分别是Compact,Redundant,Dynamic和Compressed

指定行格式的方法

语法如下:

CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称;
#修改如下
ALTER TABLE 表名 ROW_FORMA=行格式名称;

COMPACT行格式

行格式示意图
额外信息是为了描述该条记录而不得不添加的一些信息有以下三类

变长字段长度列表

 为了支持变长的数据类型,(VARCHAR,TEXT,BLOB),必须有的东西,把所有的变长字段真实数据占用的字节数放在记录的开头,形成一个变长字段长度列表,各变长字段数据占用的字节数按逆序存放
变长字段长度可能由多个字节组成,如果是多个字节(最多两个)表示长度,如果是多字节,那么每个字节的的最高位被设置成1

NULL值列表

 变长字段长度列表只存储值非NULL的列,NULL的列在NULL值列表处理
 允许存储NULL的列将组成一个NULL值列表,以位图的方式指示列是否为NULL,也是逆序排列的,并且NULL值列表的长度必须整数字节,不够的位补0
在这里插入图片描述

记录头信息

在这里插入图片描述
主要是为了构建B+树存在

删除标志delete_mask

 上文所述的记录格式(行格式)中,有一个delete_mask指示是否被删除,被删除的行会组成一个垃圾链表,称为可重用空间

heap_no

 行格式中heap_no表示在页中的相对位置,从2开始.0和1称为伪记录,伪记录指向最大与最小记录

record_type

含义
0普通记录
1B+树非叶节点
2最小记录
3最大记录

next_record

 类似C语言中的指针,值是下一个真实数据行相对当前行的地址偏移值(根据这个可以找到下一个next_record)(有序链表,以主键排序),在Mysql中会形成一个单链表
 next_record的位置正好是头信息和真实数据的分界线,这样的好处是向左读就是头信息,向右读就是真实数据
 由于next_record的特殊位置设计,变长长度和NULL值列表是倒着存的也是基于这个设计(沿next_record中心对称,读取相当方便)

n_owned

这个在下文的页部分解释

记录的真实数据

除了真实数据,MYSQL会为每个记录添加一些默认列(隐藏列)

列名是否必须占用空间备注
DB_ROW_ID6B行ID,唯一表示一条记录
DB_TRX_ID6B事务ID
DB_ROLL_PRE7B回滚指针

DB_ROW_ID只有在没有自定义主键和unique键的情况下才会添加该列

Dynamic和Compressed行格式

 类似于COMPACT行格式,不过在行溢出发生的情况下会将所有的数据都存到其他页中

行溢出

 除了TEXT和BLOL类型的数据,其他的数据不能超过65535个字节(包含了所有杂项,包括可变长和是否NULL)
 由于MYSQL的页面大小是16KB,当一个列的数据太多大于这个值是,Compact和Reduntant格式仅仅存储前768个字节,和一个指向其他页的地址(20B,这里包括其他页面中数据的真实占用计数),

行溢出的临界点

 Mysql规定一个页中至少要存放两行记录
 每个页需要136个字节存储页信息
而每个记录(MYSQL行需要额外的27个字节)
发生行溢出的临界点是 136 + 2*(n + 27) > 16KB(mysql页大小),在发生行溢出之后使用上文的处理方法

InnoDB页

 InnoDB将数据划分成若干个页,以页为单位作为**磁盘和内存交换的基本单位,页的大小一半为16KB(一次最少把16KB的数据从磁盘读入内存)
 存放记录的页(INDEX页),存储空间划分如下
在这里插入图片描述

名称描述
FileHeader页的通用信息
Page Header数据页的专有信息
Infimum + Supremum两个虚拟的行记录(最小记录和最大记录)
User Records实际存储的行记录内容
Free Space页中尚未使用的空间
Page Directory页中某些数据的相对位置
File Trailer检验页是否完整

在这里插入图片描述

pageDiretory的设计

 pageDeiretory(下面简称PD)的思想是采用二分算法,在每个行记录中有一个,PD存储多个槽,这些槽将行记录分为多个组,每个组多条记录,槽指向这些分组的最大记录,这些记录的n_owned字段存储改组有多少个记录排在他前面(在行记录格式部分详细阐述了Mysql有序性及其实现),然后通过这些槽的二分来查找主键
具体流程如下

在这里插入图片描述
 每次和这些槽指向的值(永远指向分组的最大值)比较,并且缩减区间,直到high - low == 1,然后同过low来寻找值
 为什么终止条件是high-low == 1,原因在于mysql的1如下规定
对于最小记录所在的分组只能有 1 条记录,最大记录所在的分组拥有的记录条数只能在 1~8 条之间,剩下的分组中记录的条数范围只能在是 4~8 条之间。

pageHeader设计

字段描述和功能
PAGE_N_DIR_SLOTS在页目录中的槽数量
PAGE_HEAP_TOP还未使用的空间最小地址,也就是说从该地址之后就是 Free Space
PAGE_N_HEAP 本页中的记录的数量(包括最小和最大记录以及标记为删除的记录)
PAGE_FREE第一个已经标记为删除的记录地址(各个已删除的记录通过 next_record 也会组成一个单链表,这个单链表中的记录可以被重新利用)
PAGE_GARBAGE已删除记录占用的字节数
PAGE_LAST_INSERT最后插入记录的位置
PAGE_DIRECTION记录插入的方向
PAGE_N_DIRECTION一个方向连续插入的记录数量
PAGE_N_RECS该页中记录的数量(不包括最小和最大记录以及被标记为删除的记录)
PAGE_MAX_TRX_ID修改当前页的最大事务ID,该值仅在二级索引中定义
PAGE_LEVEL当前页在B+树中所处的层级
PAGE_INDEX_ID索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAFB+树叶子段的头部信息,仅在B+树的Root页定义
PAGE_BTR_SEG_TOPB+树非叶子段的头部信息,仅在B+树的Root页定义

File Header设计

名称描述
FIL_PAGE_SPACE_OR_CHKSUM页的校验和(checksum值)
FIL_PAGE_OFFSET页号
FIL_PAGE_PREV上一个页的页号
FIL_PAGE_NEXT下一个页的页号
FIL_PAGE_LSN页面被最后修改时对应的日志序列位置(英文名是:Log Sequence Number)
FIL_PAGE_TYPE该页的类型
FIL_PAGE_FILE_FLUSH_LSN仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID页属于哪个表空间

FileTailer设计

 用于检测页是否完全被同步到了磁盘里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值