MySQL不同版本下表结构和数据存储总结

本文我们尝试研究MySQL在5.7和8.0版本下Innodb引擎与MyISAM引擎下数据库文件存储形式。

像InnoDB、MyISAM这样的存储引擎都是把表存储在磁盘上的,操作系统用来管理磁盘的结构被称为文件系统。换句话说,像InnoDB、MyISAM这样的存储引擎都是把表存储在文件系统上的。当我们想读取数据的时候,这些存储引擎会从文件系统中把数据读取出来返回给我们。当我们想写入数据的时候,这些存储引擎会把这些数据又写回文件系统。

【1】MySQL5.7

① InnoDB引擎

如下图所示,我们随意选择一个数据库进行查看,可以看到有三种文件形式:opt、frm、ibd。

opt: 包含了该数据库的各种属性,比如数据库的字符集和比较规则。

frm : 存放了表的结构,是一个二进制格式文件。

表结构就是该表的名称,表里面有多少列,每个列的数据类型、约束条件和索引,使用的字符集和比较规则等各种信息,这些信息都体现在了我们的建表语句中。

ibd: 独立表空间,存放了表的数据和索引。

在这里插入图片描述

② MyISAM

如下所示,有四种文件形式:opt、frm、MYD、MYI。可以看到与InnoDB下不同的是这里没有ibd文件而是对应拆分为了MYD和MYI。

MYD: 表数据文件。

MYI:表索引文件。

从这里也可以看出来MYISAM是把索引和数据文件分开存储,而InnoDB则索引文件即数据文件。
在这里插入图片描述

【2】MySQL8

① InnoDB

如下所示,只有ibd文件,没有其他。即数据库信息、表结构、表数据以及表索引均存储在ibd文件中。

在这里插入图片描述

② MYISAM

我们创建一个MYIASM表,插入数据,查看数据存储文件如下所示:

在这里插入图片描述

可以看到其有三个文件:sdi、MYD、MYI。sdi相当于前面我们提到过的frm文件,也是存放表结构信息的。

③ 关于sdi

在MySQL8中我们可以看到没有了 .frm 文件,那么去了哪里呢?就放在了sdi文件中。Oracle官方(MySQL8属于Oracle旗下)将frm文件的信息以及更多信息移动到叫做序列化字典信息(Serialized Dictionary Information,SDI)中,SDI在InnoDB下是被写在了ibd文件内部。

为了从ibd文件中提取SDI信息,oracle提供了一个应用程序ibd2sdi。这个工具不需要下载,MySQL8自带的有,只要配置好环境变量即可使用。

我们可以到存储ibd文件的目录下,执行如下命令:

ibd2sdi --dump-file=tb_sys_admin.txt tb_sys_admin.ibd

在这里插入图片描述

【3】表空间

InnoDB其实是使用页为基本单位来管理存储空间的,默认的页的大小为 16KB。对于InnoDB存储引擎来讲,每个索引都对应着一棵B+树,该B+树的每个节点都是一个数据页,数据页之间不必要是物理连续的,因为数据页之间有双向链表来维护着这些页的顺序。

InnoDB的聚簇索引(也就是主键索引文件)的叶子节点存储了完整的用户记录。

为了更好的管理这些页,InnoDB提出了一个表空间或者文件空间(table space or file space)的概念。这个表空间是一个抽象的概念,它可以对应文件系统上一个或多个真实文件(不同表空间对应的文件数量可能不同)。每一个表空间可以被划分为很多个,我们的表数据就存放在某个表空间下的某些里。

① 系统表空间

默认情况下,InnoDB会在数据目录下创建一个名为ibdata1、大小为12M的文件。这个文件就是对应的系统表空间在文件系统上的表示,其是自扩展文件,当不够用的时候会自己增加大小。

我们可以在MySQL启动时配置对应的文件路径以及它们的大小,比如my.cnf配置如下:

[server]
innodb_data_file_path=data1:512M;data2:512M:autoextend

这样在MySQL启动之后就会创建这两个512M大小的文件作为系统表空间,其中autoextend表明这两个文件如果不够用会自动扩展data2文件的大小。

需要注意的一点是,在一个MySQL服务器中,系统表空间只有一份。从MySQL5.5.7到MySQL5.6.6之间的各个版本中,我们表中的数据都会被默认存储到这个系统表空间。

② 独立表空间(file-per-table-tablespace)

在MySQL5.6.6以及之后的版本中,InnoDB并不会默认的把各个表的数据存储到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多少个表,就有多少个独立表空间。

使用独立表空间来存储表数据的话,会在该表所属数据库对应的子目录下创建一个表示该独立表空间的文件,文件名和表名相同,只不过添加了一个 .ibd 的扩展名而已。

③ 系统表空间与独立表空间的设置

我们可以自己指定使用系统表空间还是独立表空间来存储数据,这个功能由启动参数innodb_file_per_table来控制,比如说我们想刻意将表数据都存储到系统表空间时,可以在启动MySQL服务器的时候这样配置:

[server]
innodb_file_per_table=0 # 0 : 使用系统表空间;1 : 使用独立表空间

默认该值是1,可以使用如下命令查看:

show variables  like '%innodb_file_per_table%'

该参数的修改对新建的表起作用,对于已经分配了表空间的表并不起作用。如果我们想把已经存在系统表空间中的表转移到独立表空间,可以使用下边的语法:

alter table 表名 tablespace [=] innodb_file_per_table;

或者把已经存在独立表空间的表转移到系统表空间,可以使用下边的语法:

alter table 表名 tablespace [=] innodb_system;

④ 其他类型的表空间

随着MySQL的发展,除了上述两种老牌表空间之外,现在还新提出了一些不同类型的表空间,比如通用表空间(general tablespace)、临时表空间(temporary tablespace)等。

猜你喜欢

转载自blog.csdn.net/J080624/article/details/72866822/