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

怎么手动分析 InnoDB 数据存储和索引结构

最近和一些小伙伴一起在研究 MySQL 相关的理论知识,看磁盘存储的信息其实可以自己手动实践一下的,这个其实很简单,但有些小伙伴没有这方面的知识,不知道怎么上手。我这里写一篇简单的教程,我使用的是 8.0.23 版本。

1. 创建数据库和表

首先,我们创建一个简单的表来存储数据。执行以下 SQL 语句:

CREATE TABLE `test10` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL DEFAULT '',
  `age` int NOT NULL DEFAULT '0',
  `sex` char(3) NOT NULL DEFAULT 'N',
  `text1` varchar(100) NULL DEFAULT NULL,
  `text2` varchar(100) NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

创建完表之后,我们可以到 MySQL 的数据文件目录下找到一个名字叫 test10.ibd 的文件。
如果不知道 MySQL 的数据文件目录,可以执行 show variables like 'datadir'; 查看。我的数据库名称是 test1 ,这个目录下就看到了创建的表的 ibd 文件。
在这里插入图片描述

2. 插入数据并查看磁盘存储

接下来,我们向表中插入一条数据:

INSERT INTO `test10` (`name`, `age`, `sex`, `text1`, `text2`) VALUES('yuan01', 0, 'N', 'aaa', 'bbbb');

使用 hexdump 命令查看该文件内容:

hexdump -C test10.ibd

在这里插入图片描述

3. 分析数据存储结构

忽略不认识的内容,快速跳到我们熟悉的数据部分。只插入了一条数据的情况下,我们可以直接拉到文件底部。
在这里插入图片描述

这是我拉到最底下的截图,红色框内的就是聚簇索引,也是表数据;蓝色框内的就是辅助索引

这个截图中,每两个字符代表一个字节,它们是十六进制的。比如说,为什么我知道 79 75 61 6e 30 31 就是 yuan01
首先,可以通过右边看到;其次,这是 ASCII 码。我们可以拿 ASCII 对照表来看,直接对照右边的内容,更容易识别。

用浅色小框框住的 45bf 表示该页的类型是索引页。因此,在 InnoDB 中,表数据和索引数据类型都属于索引页。如果一张表没有辅助索引,那么它就只有一个聚簇索引,也就是一个 B+ 树;如果有辅助索引,就会有两个 B+ 树(包括了聚簇索引的)。

我们所说的“不需要回表”,意思是只操作索引。我们从这个视角来看,辅助索引也可以看做是一个独立的数据表,它的主键是索引列,而字段则是索引列和主键字段的组合。

接下来,我们来看数据:

红色框 聚簇索引部分

黄色横线 标出的 yuan01 就是我们的 name 字段。

蓝色横线 标出的 Nxxsex 字段,其中 x 代表空格,空格显示不出来。这里,我们可以看到,CHAR 类型的字段会用空格填充至固定长度。20ASCII 码对应的空格,20 是十六进制值表示,而十进制是 32

绿色横线 标出的部分是 VARCHAR 类型字段的字节数记录。在这里,我们可以看到 VARCHAR 在存储时会占用多少字节。在这个例子中,这里的字节数占了 4 个字节,我们有 3 个 varchar 类型,1 个 char 类型,CHAR 类型字段也会在这里标识出它的长度。
这些长度信息是倒序存储的,04 03 03 06 代表了各个字段的字节数:bbbb 占了 4 个字节,aaa 占了 3 个字节,Nxx 占了 3 个字节,yuan01 占了 6 个字节。如果我们使用中文字符,比如 测试aa,它将占用 8 个字节,因为使用的是 utf8mb4 字符集,每个中文字符占 3 个字节。

为什么绿色横线的位置保存长度而不是其他地方呢?因为在主键前的 6 个字节是行记录头,这是 InnoDB 定义的存储格式。

红色横线 标出的是主键ID,至于为什么最高位是 1,这点我还没有完全搞明白。

为什么这个位置是主键ID?因为主键后面会有 13 个字节,这些字节分别存储事务ID回滚指针。因此,通过从 yuan01 开始往前数,我们就能找到主键ID

蓝色框 辅助索引部分

这个简单点两个红色横线标出的分别是 索引列值主键 ID

其他的一些细节,可以通过实际操作自行验证。我的理解就到这里了。

相关文章:

  • 漏洞分析 Spring Framework路径遍历漏洞(CVE-2024-38816)
  • Spring Boot延迟执行实现
  • MySQL 简介
  • 创建React项目的三个方式
  • 大规模分布式处理系统:语言选择与任务分配机制
  • nginx容器配置fastapi服务失败
  • Mockito:Java单元测试中的模拟框架
  • 定时器的知识点总结
  • Seata 分布式事务框架:从下载到实战配置全解析
  • 10. 九转金丹炼矩阵 - 矩阵置零(标记优化)
  • 【练习】【回溯:分割】力扣131. 分割回文串
  • Win11作为宿主机,运行VMware 总没有网络
  • 21.《SpringBoot 异步编程@Async与CompletableFuture》
  • Linux系统移植之Uboot启动流程
  • MySQL(高级特性篇)11章——数据库的设计规范
  • 电商运营中私域流量的转化与变现:以开源AI智能名片2+1链动模式S2B2C商城小程序为例
  • 【Linux】常用命令(Ubuntu系统)
  • NSFNET是什么?NSFNET网络具有什么特点?
  • numpy中axis问题记录
  • 遥控器控制nefflix优化
  • 高端建设网站公司/谷歌广告投放教程
  • 做网站比较大的公司/西安楼市最新房价
  • 哪个行业最需要做网站/搜索排名优化公司
  • dreamweaver cs6/网站优化seo推广服务
  • 1网站建设/深圳网站设计专业乐云seo
  • 云建站app/seo免费培训