【MySQL进阶】深入理解InnoDB记录结构

news2024/11/18 4:49:01

【MySQL进阶】深入理解InnoDB记录结构

参考资料:《MySQL是怎么运行的:从根儿上理解MySQL》。

前言:

我们一般使用的MySQL关系型数据库,更是经典中的经典,虽说MySQL已经非常成熟,但对于MySQL的掌握程度,如果我们只停留在使用层面,不了解它的底层设计,那咱永远只能停留在写SQL上,成为一个彻头彻尾的CRUDBoy。

一:InnoDB页简介

InnoDB 是一个将表中的数据存储到磁盘上的存储引擎,所以即使关机后重启我们的数据还是存在的。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内存中的内容刷新到磁盘上。而我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级,所以当我们想从表中获取某些记录时, InnoDB 存储引擎需要一条一条的把记录从磁盘上读出来么?不,那样会慢死,InnoDB 采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16 KB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。

二:InnoDB行格式

行格式简介

我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。
InnooDB目前有四种行格式:

  • compact(简洁的)
  • redundant(冗余的)
  • dynamic(动态的)
  • compress(压缩的)

创建表可以这样指定它的 行格式 :

mysql> CREATE TABLE record_format_demo (
-> c1 VARCHAR(10),
-> c2 VARCHAR(10) NOT NULL,
-> c3 CHAR(10),
-> c4 VARCHAR(10)
-> ) CHARSET = ascii ROW_FORMAT = COMPACT;

COMPACT行格式

废话不多说,直接看图:

image-20221026171111339

一条完整的记录其实可以被分为 记录的额外信息记录的真实数据 两大部分

变长字段长度列表

MySQL 支持一些变长的数据类型,比如 VARCHAR(M) 、 VARBINARY(M) 、各种 TEXT 类型,各种 BLOB 类型,变长字段中存储多少字节的数据是不固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来,这样才不至于把 MySQL 服务器搞懵。

在 Compact 行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放,我们再次强调一遍,是逆序存放!

image-20221026171932292

如上图,其 变长字段长度列表 的效果为:

image-20221026172026887

另外需要注意的一点是,变长字段长度列表中只存储值为 非NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的 。

NULL值列表

如果表中没有允许存储 NULL 的列,则 NULL值列表 也不存在了,否则将每个允许存储 NULL 的列对应一个二进制位,二进制位按照列的顺序逆序排列,二进制位表示的意义如下:

  • 二进制位的值为 1 时,代表该列的值为 NULL 。
  • 二进制位的值为 0 时,代表该列的值不为 NULL 。
  • MySQL 规定 NULL值列表 必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补 0 。

image-20221026175247019

image-20221026175335419

所以这两条记录在填充了 NULL值列表 后的示意图就是这样:

image-20221026175406601

记录头信息

用于描述记录的记录头信息,它是由固定的5个字节组成。也就是40个二进制位,不同的位代表不同的意思。

image-20221026175507943

这些二进制位代表的详细信息如下表:(只需要看一遍混个脸熟,等之后用到这些属性的时候我们
再回过头来看)

image-20221026175558963

记录的真实数据

对于 record_format_demo 表来说, 记录的真实数据 除了 c1 、 c2 、 c3 、 c4 这几个我们自己定义的列的数据以外, MySQL 会为每个记录默认的添加一些列(也称为 隐藏列 ),具体的列如下:

image-20221026175711411

InnoDB 表对主键的生成策略:

优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个 Unique 键作为主键,如果表中连 Unique 键都没有定义的话,则 InnoDB 会为表默认添加一个名为row_id 的隐藏列作为主键。

因为表 record_format_demo 并没有定义主键,所以 MySQL 服务器会为每条记录增加上述的3个列。现在看一下加上 记录的真实数据 的两个记录长什么样吧:

image-20221026175843625

CHAR(M)列的存储格式

record_format_demo 表的 c1 、 c2 、 c4 列的类型是 VARCHAR(10) ,而 c3 列的类型是 CHAR(10) ,我们说在Compact 行格式下只会把变长类型的列的长度逆序存到 变长字段长度列表 中。

但是这只是因为我们的 record_format_demo 表采用的是 ascii 字符集,这个字符集是一个定长字符集,也就是说表示一个字符采用固定的一个字节,如果采用变长的字符集(也就是表示一个字符需要的字节数不确定,比如gbk 表示一个字符要12个字节、 utf8 表示一个字符要13个字节等)的话, c3 列的长度也会被存储到 变长字段长度列表 中。

image-20221026181815967

image-20221026181821951

这就意味着:对于 CHAR(M) 类型的列来说,当列采用的是定长字符集时,该列占用的字节数不会被加到变长字段长度列表,而如果采用变长字符集时,该列占用的字节数也会被加到变长字段长度列表。

另外有一点还需要注意,变长字符集的 CHAR(M) 类型的列要求至少占用 M 个字节,而VARCHAR(M) 却没有这个要求。比方说对于使用 utf8 字符集的 CHAR(10) 的列来说,该列存储的数据字节长度的范围是10~30个字节。即使我们向该列中存储一个空字符串也会占用 10 个字节,这是怕将来更新该列的值的字节长度大于原有值的字节长度而小于10个字节时,可以在该记录处直接更新,而不是在存储空间中重新分配一个新的记录空间,导致原有的记录空间成为所谓的碎片。

Redundant行格式

其实知道了 Compact 行格式之后,其他的行格式就是依葫芦画瓢了。我们现在要介绍的Redundant 行格式是MySQL5.0 之前用的一种行格式,也就是说它已经非常老了。

————暂时不记录…

Dynamic和Compressed行格式

下边要介绍另外两个行格式, Dynamic 和 Compressed 行格式,我现在使用的 MySQL 版本是 5.7,它的默认行格式就是 Dynamic ,这俩行格式和 Compact 行格式挺像,只不过在处理 行溢出 数据时有点儿分歧,它们不会在记录的真实数据处存储字段真实数据的前 768 个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址,就像这样:

image-20221026182813125

Compressed 行格式和 Dynamic 不同的一点是, Compressed 行格式会采用压缩算法对页面进行压缩,以节省空间。

三:总结

1:页是 MySQL 中磁盘和内存交互的基本单位,也是 MySQL 是管理存储空间的基本单位。

2:InnoDB 目前定义了4种行格式

  • COMPACT行格式

image-20221026183106564

  • Redundant行格式

image-20221026183253376

  • Dynamic和Compressed行格式
    • 这两种行格式类似于 COMPACT行格式 ,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处存储字符串的前768个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。
    • 另外, Compressed 行格式会采用压缩算法对页面进行压缩。

3:一个页一般是 16KB ,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为 行溢出 。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯Java888道高频面试真题笔记+Java面试宝典

这多半年你是否达到了你年初定的目标,今年企业招聘要求也是更加的严格,对于低学历,以及技术实力不过关的更是雪上加霜。也是由于种种缘由,从5月开始就一直有粉丝私信要博主整理一些干货来帮助他们提升下自己,为了响应粉丝要求&…

Non-Autoregressive Coarse-to-Fine Video Captioning【论文阅读】

Non-Autoregressive Coarse-to-Fine Video Captioning 发表:AAAI 2021idea:(1)针对推理阶段不能并行,推理效率低的问题使用一种双向解码(在bert中不使用sequence mask)。(2&#xf…

基于QD求解法的二分类SVM仿真

目录 1.算法概述 2.部分程序 3.算法部分仿真结果图 4.完整程序获取 CSDN用户:我爱C编程 CSDN主页:https://blog.csdn.net/hlayumi1234567?typeblog 擅长技术:智能优化,路径规划,通信信号,图像处理&…

【数据结构与算法分析】0基础带你学数据结构与算法分析06--树(TREE)

目录 前言 树的属性 树的实现 树的遍历与应用 深度有限遍历 (DFS) 广度优先遍历 (BFS) Not all roots are buried down in the ground, some are at the top of a tree. — Jinvirle 前言 Tree 是一些结点的集合,这个集合可以是空集;若不是空集…

【模型训练】YOLOv7行人检测

YOLOv7行人检测 1、YOLOv7算法行人检测模型训练2、YOLOv7模型模型评估3、模型和数据集下载1、本项目采用YOLOv7算法实现对行人的检测和识别,在一万多张行人检测数据集中训练得到,我们训练了YOLOv7模型,经评估我们得出了各个模型的评价指标; 2、目标类别数:1 ;类别名:pers…

笔试强训第15天(手套+ 查找输入整数二进制中1的个数)

选择 C barfoob_bar new B 会先创建一个B类对象,B类对象的构造需要调用B的构造函数,从而调用A的构造函数。A的构造函数中调用了 bar()函数,该函数虽然重写了,但这里不构成多态调用。因为虚表中的函数指针是在构造函数的初始化列表…

爱上源码,重学Spring IoC深入

回答: 我们为什么要学习源码? 1、知其然知其所以然 2、站在巨人的肩膀上,提高自己的编码水平 3、应付面试1.1 Spring源码阅读小技巧 1、类层次藏得太深,不要一个类一个类的去看,遇到方法该进就大胆的进 2、更不要一行…

【3D目标检测】SECOND: Sparsely Embedded Convolutional Detection

目录概述细节网络结构稀疏卷积方向分类损失函数概述 首先,本文是基于点云,并且将点云处理成体素的3D目标检测网络,提出的SECOND可以看做是VoxelNet的升级版。 提出动机与贡献 VoxelNet计算量比较大,速度比较慢(训练和…

第二节:数据类型与变量【java】

目录 📃前言 📗1.数据类型 📕2. 变量 2.1 变量概念 2.2 语法格式 📙3.整型变量 3.1 整型变量 3.2 长整型变量 3.3 短整型变量 3.4 字节型变量 📘4.浮点型变量 4.1 双精度浮点型 4.2 单精度浮点型 &#…

[SpringBoot] AOP-AspectJ 切面技术

✨✨个人主页:沫洺的主页 📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专…

python的编译器与解释器

作者介绍: 🐥作者:小刘在C站 👆每天分享课堂笔记,一起努力,共赴美好人生 🍁夕阳下,是最美的绽放 目录 一.为什么会有编译器和解释器 二.编译器和解释器的区别 三.python解释器种类…

RK3399应用开发 | 移植libdrm到rk3399开发板(2.4.113)

一、下载源码 下载地址:https://dri.freedesktop.org/libdrm/。 这里我下载最新的2.4.113版本: wget https://dri.freedesktop.org/libdrm/libdrm-2.4.113.tar.xz解压: xz -d libdrm-2.4.113.tar.xz tar -xf libdrm-2.4.113.tar二、编译环境安装 1. 更新python ubuntu安…

CalBioreagents 艾美捷重组BCOADC-E2蛋白说明书

艾美捷CalBioreagents 重组BCOADC-E2蛋白英文说明: PRODUCT DESCRIPTION: Branched Chain 2-Oxo-Acid Dehydrogenase Complex E2 protein, recombinant. CLINICAL INDICATION: Primary biliary cirrhosis CATALOG NUMBER: A268 SOURCE: Recombinant protein ex…

《CTF攻防世界web题》之茶壶我爱你(2)

前言 🍀作者简介:被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 🍁个人主页:被吉师散养的职业混子 🫒文章目的:记录唯几我能做上的题 🍂相应专栏:CT…

Pytorch调用GPU时显示CUDA版本过低的解决方案

在调用torch.cuda.is_available时,有如下报错: cuda initialization: The Nvidia driver on your system is too old. 事情的发展是这样的: 1. 服务器的CUDA版本是10.1,仅支持pytorch版本最高1.7;前几天跑项目需要用…

Oracle 中常用的字符串函数总结

一、substr 函数 —— 字符串截取 格式1: substr(string,start_pos,length) 格式2: substr(string,start_pos) 说明: 从指定位置start_pos截取字符串string的length位,如果不指定length(格式2)则从指…

【数据挖掘】2022数据挖掘之Pandas库相关使用

数据挖掘之Pandas库相关使用一、概念1、介绍2、Pandas的优点3、软件推荐(Jupyter Notebook)4、软件下载网址以及参考文档二、基础知识1、DataFrame属性和方法1.1 结构(1)行索引(2)列索引1.2 常用属性&#…

配置非法AP设备检测和反制

1、业务需求 某企业分支机构为了保证工作人员可以随时随地访问公司网络资源,部署WLAN基本业务实现移动办公。且在覆盖区域内移动发生漫游时,不影响用户的业务使用。 分支机构位于开放式场所,容易受到网络入侵,例如攻击者在WLAN网络…

摒弃“短板”——数据中心基础设施运维管理建议书

数据中心是数字基础设施的重要组成部分,同时也是一整套复杂的设施。它不仅仅包括计算机系统和其它与之配套的设备(例如通信和存储系统),还包含冗余的数据通信连接、环境控制系统、监控系统以及各种安全系统。运维管理又是数据中心…

基于智能优化算法实现自动泊车的路径动态规划(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 作为一种方便、快捷的交通工具,汽车已成为人们生活和工作的重要组成部分。随着汽车数量的逐年增加,有限…