InnoDB详解2

news/2024/12/29 19:01:01/

文章目录

  • InnoDB详解2
  • 1 行格式
      • 1 Compact行格式详解
        • 1 变长字段长度列表(两个字节)
        • 2 NULL值列表(1个字节)
        • 3 记录头信息 (重点)
      • 2 Dynamic行格式
  • 2 页的上层结构

InnoDB详解2

1 行格式

规定每条记录是怎么存储的
MySQL 8默认行格式是Dynamic

InnoDB存储引擎设计了4种不同类型的`行格式`,分别是`Compact`、`Redundant`、`Dynamic`和`Compressed`行格式。
查看MySQL8的默认行格式:
mysql> SELECT @@innodb_default_row_format;
+-------------------------------------+
| @@innodb_default_row_format |
+-------------------------------------+
| dynamic                                   |
+-------------------------------------+
1 row in set (0.00 sec)
也可以使用如下语法查看具体表使用的行格式:
SHOW TABLE STATUS like '表名'\G

1 Compact行格式详解

image-20221223101452542

1 变长字段长度列表(两个字节)

在每条记录开始存入变长字段列表。没有变长字段就没有该项。小端存储。

如VARCHAR(M)、VARBINARY(M)、TEXT类型,BLOB类型,这些数据类型修饰列称为变长字段,变长字段中存储多少字节的数据不是固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表

image-20221223101918763

2 NULL值列表(1个字节)

为什么定义NULL值列表?

之所以要存储NULL是因为数据都是需要对齐的,如果没有标注出来NULL值的位置,就有可能在查询数据的时候出现混乱。如果使用一个特定的符号放到相应的数据位表示空置的话,虽然能达到效果,但是这样很浪费空间,所以直接就在行数据得头部开辟出一块空间专门用来记录该行数据哪些是非空数据,哪些是空数据

用于标识哪些是null值,1位null ,0不为null。允许为null的字段才会有该记录。

明确表明该字段不为null值时,不会记录

如 一条记录 有 ABC 三个字段 A是主键 BC可以为null 该记录 A = 1 ,B= null ,C = 2, NULL值列表存的是 0 1 ,0表示C不是null,1表示 B是null。A是主键不能为null 所以不用存。

3 记录头信息 (重点)

image-20221223103105152

image-20221223103153625

image-20221223104814392

delete_mask:当删除数据时,只需要将delete_mask标识位1。

占用1个二进制位。

  • 值为0:代表记录并没有被删除

  • 值为1:代表记录被删除掉了

被删除的记录为什么还在页中存储呢?

这些被删除的记录之所以不立即从磁盘上移除,是因为移除它们之后其他的记录在磁盘上需要重新排列,导致性能消耗。所以只是打一个删除标记而已,所有被删除掉的记录都会组成一个所谓的垃圾链表,在这个链表中的记录占用的空间称之为可重用空间,之后如果有新记录插入到表中的话,可能把这些被删除的记录占用的存储空间覆盖掉。

min_rec_mask:B+树的每层非叶子节点中的最小记录都会添加该标记,min_rec_mask值为1。

record_type:

这个属性表示当前记录的类型,一共有4种类型的记录:

0:表示普通记录

1:表示B+树非叶节点记录

2:表示最小记录

3:表示最大记录

heap_no:每条记录在此页中的位置,(Infimum )最小记录和(Supremum)最大记录的heap_no值分别是0和1,其他记录往后顺延。

**n_owned :**页目录中每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned 字段。分组也叫slot槽,槽位记录的是最大记录的地址偏移,最后一条记录记录该组中有几条记录。

**next_record:**从当前记录的真实数据到下一条记录的真实数据的地址偏移量

image-20221223110220833

删除操作

image-20221223110429030

删除第二条记录时,先根据页目录二分查找到 槽位,然后进行遍历,遍历到第二条记录,delete_mask改为1,next_record改为0,第一条记录链接到第三条记录。该分组中 最后一条记录的n_owned由5变为4 (最小记录自成一组)

当数据页中存在多条被删除掉的记录时,这些记录的next_record属性将会把这些被删除掉的记录组成一个垃圾链表,以备之后重用这部分存储空间。

所以,不论我们怎么对页中的记录做增删改操作,InnoDB始终会维护一条记录的单链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的

添加操作

image-20221223111331148

2 Dynamic行格式

MySQL对一条记录占用的最大存储空间是有限制的,除BLOB或者TEXT类型的列之外, 其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。

这个65535个字节除了列本身的数据之外,还包括一些其他的数据,以Compact行格式为例,比如说我们为了存储一个VARCHAR(M)类型的列,除了真实数据占有空间以外,还需要记录的额外信息。

如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为变长字段的长度占用 2个字节,NULL值标识需要占用1个字节。

CREATE TABLE varchar_size_demo(

c VARCHAR(65532)

) CHARSET=ascii ROW_FORMAT=Compact;

如果有not null属性,那么就不需要NULL值标识,也就可以多存储一个字节,即65533个字节

我们可以知道一个页的大小一般是16KB,也就是16384字节,而一个VARCHAR(M)类型的列就最多可以存储65533个字节,这样就可能出现一个页存放不了一条记录,这种现象称为行溢出

CompactReduntant行格式中,存不下的数据就存一部分数据和其他数据的页地址,其他数据放到其他页中。

CompressedDynamic两种记录格式对于存放在BLOB中的数据采用了完全的行溢出的方式。如图,在数据页中只存放20个字节的指针(溢出页的地址),实际的数据都存放在Off Page(溢出页)中。

image-20221223112438374

所以 Dynamic 与Compact的区别就是对行溢出处理不一样,dynamic只存溢出页的地址,compact还存了一部分数据。

2 页的上层结构

image-20221223112830884

​ 页中由一条条行记录构成,我们知道页之间是由双向链表连接的。如果连续的两个页之间真实地址相隔很远。磁盘寻道扫描速度很慢,

如果一个查询需要用到100个数据页,最坏情况下需要磁盘扫描100次。为了减少IO次数,所以有了区的概念

image-20221223113332702

在数据扫描时,要先获取非叶子节点,如果将叶子节点与非叶子节点存放到一个区中,我们要的是叶子节点的数据,此时这个区中叶子节点数据很少,大部分是非叶子节点,获取真实数据时,还要扫描其他区,为了避免这种情况,引入了段的概念

image-20221223113902661

也就是将叶子节点数据放到一个区中,非叶子节点放到一个区中,专门存叶子节点或者专门存非叶子节点的区就叫做段,创建一个索引时就会分配2个段。

表空间是一个逻辑概念。

碎片区

此时创建一个表,插入一条数据。若按照 区,段的划分,此时一条数据就要构建一个聚簇索引 要分配两个区。需要 16k * 64 * 2 = 2M的空间。(一个页16K,一个区有64页,索引有叶子节点与非叶子节点 要两个段)很浪费空间。

就引入了碎片区的概念

碎片区属于表空间,该碎片去可以存段A的数据,也可以存段B的数据,就是什么都能存。

所以新建表的空间分配策略是,先找个碎片区分配空间,当一个表占用32个碎片区页面后,就会申请完整的区来存储数据。


http://www.ppmy.cn/news/6088.html

相关文章

不同截止高度角BDS/GPS/Galileo单历元RTK定位性能分析

摘要 【目的】为探究北斗卫星导航系统(BeiDou Navigation Satellite System, BDS)、GPS(Global Positioning System)、Galileo单系统及组合系统在中国地区不同截止高度角下单历元双频RTK(Real-Time Kinematic)定位性能,对武汉境内一条短基线进行分析研究。【方法】采用双…

Linux tracepoint 简介

文章目录前言一、跟踪点的目的二、跟踪点的使用三、DECLARE_TRACE四、sched_switch例程五、TRACE_EVENT六、跟踪点的开销参考资料前言 跟踪点是放置在内核代码中较重要位置的硬编码检测点。例如,在系统调用、调度程序事件、文件系统操作和磁盘I/O的开始和结束处都有…

Three JS 调研

0. 结论 three.js是使用WebGL来绘制三维效果的,核心数据是3D对象和三维模型,更多的是关注如何通过webgl更精细而美的渲染数据 three.js相当于封装了webgl,但还是很底层,并不是一个类似于cesium或者mapbox这样的成熟地图框架&…

jQuery 插件开发

文章目录jQuery 插件开发插件概述常用插件文本溢出:dotdotdot.js单行文本省略多行文本省略延迟加载:lazyload.js插件编写方法类插件函数类插件jQuery 插件开发 插件概述 jQuery插件可以理解成是使用jQuery来封装的一个功能或特效。 一般来说&#xff…

Mac 截图工具 iShot Pro - 软件介绍、下载安装详细教程

Mac 截图工具 iShot Pro -软件介绍、下载安装详细教程 iShot -优秀,功能齐全的区域截图,窗口截图,多窗口截图,长屏幕截图,shell截图,时间间隔截图,快速注释,纹理,颜色匹配…

消息中间件Kafka快速入门

前言 Kafka是基于zookeeper管理的,所以要先安装zookeeper,如果是单机模式,zookeeper安装比较简单,本文就介绍一下单机如何搭建kafka,以及基本的java demo。 环境搭建 Zookeeper 安装 http://mirrors.cnnic.cn/apac…

Python 函数用法和底层分析

【无限嚣张(菜菜)】:hello您好,我是菜菜,很高兴您能来访我的博客,我是一名爱好编程学习研究的菜菜,每天分享自己的学习,想法,博客来源与自己的学习项目以及编程中遇到问题…

详细设计说明书(GB8567——88)基于协同的在线表格forture-sheet

详细设计说明书 1引言 1.1编写目的 该文档在概要设计的基础上,进一步的细化系统结构,展示了软件结构的图标,物理设计、数据结构设计、及算法设计、详细的介绍了系统各个模块是如何实现的,包括涉及到的算法,逻辑流程…