MySQL相关(番外篇)- innodb 逻辑存储结构

3,496 阅读6分钟

前言

前面已经写了有两篇章长度的文章,第三篇我一直在寻思着要写什么(其实并没有),按照脑图来的话,这篇文章我们该来讲讲关于索引的知识了,这可是 MySQL 性能优化很关键的知识点,千万千万不要错过,不过我这里会相对比较深入地探究,相信大家读完之后多少会有点收获。

先送上两张飞机票🛬还没读过前面文章的伙伴可以先前往阅读,由浅入深: MySQL相关(一)- 一条查询语句是如何执行的 MySQL相关(二)- 一条更新语句是如何执行的

由于索引的知识点比较多,官网的内容也很多,如果大家想详细了解可以到官网,想先通读了解的话可以先看看我对索引的总结,这一章节分为三部分来讲:

  1. innodb 逻辑存储结构需要了解,作为番外篇 MySQL相关(番外篇)- innodb 逻辑存储结构
  2. 索引的数据结构也作为另外的篇章,通过对查询算法的数据模型进行演算分析 MySQL相关(三)- 索引数据模型推演及 B+Tree 的详细介绍
  3. 对索引的使用及优化规则也会作为单独的篇章 MySQL相关(四)- 性能优化关键点索引

前面提到的脑图如下,想要完整高清图片可以到微信我的公众号下【6曦轩】下回复 MySQL 脑图获取:

在这里插入图片描述

正文

innodb 逻辑存储结构

dev.mysql.com/doc/refman/… dev.mysql.com/doc/refman/…

MySQL 的存储结构分为 5 级:表空间、段、簇、页、行。

在这里插入图片描述

表空间 Table Space

上一篇文章讲磁盘结构的时候提到过,表空间可以看做是 InnoDB 存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。分为:系统表空间、独占表空间、通用表空间、 临时表空间、Undo 表空间。

段 Segment

表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等,段是一个逻辑的概念。一个 ibd 文件(独立表空间文件)里面会由很多个段组成。

创建一个索引会创建两个段,一个是索引段:leaf node segment,一个是数据段:non-leaf node segment。索引段管理非叶子节点的数据。数据段管理叶子节点的数据。

也就是说,一个表的段数,就是索引的个数乘以 2。

簇 Extent

一个段(Segment)又由很多的簇(也可以叫区)组成,每个区的大小是 1MB(64个连续的页)。

每一个段至少会有一个簇,一个段所管理的空间大小是无限的,可以一直扩展下去,但是扩展的最小单位就是簇。

页 page

为了高效管理物理空间,对簇进一步细分,就得到了页。簇是由连续的页(Page)组成的空间,一个簇中有 64 个连续的页。 (1MB/16KB=64)。这些页面在物理上和逻辑上都是连续的。

跟大多数数据库一样,InnoDB 也有页的概念(也可以称为块),每个页默认 16KB。

页是 InnoDB 存储引擎磁盘管理的最小单位,通过 innodb_page_size 设置。

一个表空间最多拥有 2^32 个页,默认情况下一个页的大小为 16KB,也就是说一个表空间最多存储 64TB 的数据。

注意,文件系统中,也有页的概念。

操作系统和内存打交道,最小的单位是页 Page。文件系统的内存页通常是 4K。

在这里插入图片描述

SHOW VARIABLES LIKE 'innodb_page_size';

假设一行数据大小是 1K,那么一个数据页可以放 16 行这样的数据。

举例:一个页放 3 行数据。

在这里插入图片描述

往表中插入数据时,如果一个页面已经写完,产生一个新的叶页面。如果一个簇的所有的页面都被用完,会从当前页面所在段新分配一个簇。

如果数据不是连续的,往已经写满的页中插入数据,会导致叶页面分裂:

连续

不连续

行 Row(仅供了解)

InnoDB 存储引擎是面向行的(row-oriented),也就是说数据的存放按行进行存放。

dev.mysql.com/doc/refman/…

Antelope[ˈæntɪləʊp](羚羊)是 InnoDB 内置的文件格式,有两种行格式:

REDUNDANT[rɪˈdʌndənt] Row Format

COMPACT Row Format(5.6 默认)

Barracuda[ˌbærəˈkjuːdə](梭子鱼)是 InnoDB Plugin 支持的文件格式,新增了 两种行格式:

DYNAMIC Row Format(5.7 默认) COMPRESSED Row Format

文件格式 行格式 描述
Antelope (Innodb-base) ROW_FORMAT=COMPACT ROW_FORMAT=REDUNDANT Compact 和 redumdant 的区别在就是在于首部的存 存内容区别。 compact 的存储格式为首部为一个非 NULL 的变长字 段长度列表 redundant 的存储格式为首部是一个字段长度偏移 列表(每个字段占用的字节长度及其相应的位移)。 在 Antelope 中对于变长字段,低于 768 字节的,不 会进行 overflow page 存储,某些情况下会减少结果 集 IO.
Barracuda (innodb-plugin) ROW_FORMAT=DYNAMIC ROW_FORMAT=COMPRESSED 这两者主要是功能上的区别功能上的。 另外在行 里的变长字段和 Antelope 的区别是只存 20 个字节, 其它的 overflow page 存储。 另外这两都需要开启 innodb_file_per_table=1

innodb_file_format 在配置文件中指定;row_format 则在创建数据表时指定。

show variables like "%innodb_file_format%"; SET GLOBAL innodb_file_format=Barracuda;

在这里插入图片描述

在创建表的时候可以指定行格式。

CREATE TABLE tf1 (c1 INT PRIMARY KEY) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;

查看行格式:

SHOW TABLE STATUS LIKE 'student' \G;

在这里插入图片描述
这一块的内容主要是让大家了解页 page 的概念。 接下来我们可以到MySQL相关(三)- 索引数据模型推演及 B+Tree 的详细介绍查看关于索引数据结构的演算。

By the way

有问题?可以给我留言或私聊 有收获?那就顺手点个赞呗~

当然,也可以到我的公众号下「6曦轩」,

回复“学习”,即可领取一份 【Java工程师进阶架构师的视频教程】~

回复“面试”,可以获得: 【本人呕心沥血整理的 Java 面试题】

回复“MySQL脑图”,可以获得 【MySQL 知识点梳理高清脑图】

由于我咧,科班出身的程序员,php,Android以及硬件方面都做过,不过最后还是选择专注于做 Java,所以有啥问题可以到公众号提问讨论(技术情感倾诉都可以哈哈哈),看到的话会尽快回复,希望可以跟大家共同学习进步,关于服务端架构,Java 核心知识解析,职业生涯,面试总结等文章会不定期坚持推送输出,欢迎大家关注~~~

在这里插入图片描述