mysql三个范式(说说什么是页分裂吧)

1

前言

create出来的table其实是属于一个表空间的,而所谓的表空间其实对应着一个真实存在于物理磁盘上的文件。

InnoDB从磁盘中读取数据的最小单位是数据页。而你想得到的id = xxx的数据,就是这个数据页众多行中的一行。

下面我们就一起看下,究竟什么是MySQL的数据页、数据区等概念。

2

数据页长啥样?

mysql三个范式(说说什么是页分裂吧)(1)

我猜你原来肯定多次看到过这个图!没错它就是数据页的逻辑视图。

其实上图中的每一部分都能再细分成多少byte是XXX,多少byte是YYY。但是我感觉没必要再分的那么细了,那么多字段我都整出来想必大家也不会看。看了也容易忘,所以将忘就忘,就简单的罗列几个每部分存储着什么作用的数据给大家看。

在innodb存储引擎中,数据页是InnoDB磁盘管理的最小的数据单位,数据页的默认大小为16KB。

单个数据页的大小并不是一成不变的。

在MySQL5.6中:你可以通过参数innodb_page_size设置每个数据页的大小为4KB、8KB、16KB。一旦设置完成后,所有表中的数据页大小都将是你设置的值且不可变。不论你将innodb_page_size设置成多大,一个区(extent)1MB的事实都不会改变。

在MySQL5.7.6中:允许你将innodb_page_size 设置成 32KB、64KB大小。对于32KB大小的数据页来说区的大小被调整成2MB。对于64KB大小的数据页来说,区的大小被调整成4MB。

3

什么是数据区?

在MySQL的设定中,同一个表空间内的一组连续的数据页为一个extent(区),默认区的大小为1MB,页的大小为16KB。16*64=1024,也就是说一个区里面会有64个连续的数据页。连续的256个数据区为一组数据区。

于是我们可以画出这张图:

mysql三个范式(说说什么是页分裂吧)(2)

直观上看,其实不用纳闷为啥MySQL按照这样的方式组织存储在磁盘上的数据。

这就好比你搞了个Java的封装类描述一类东西,然后再相应的给它加上一些功能方法,或者用golang封装struct去描述一类对象。最终的目的都是为了方便、管理、控制。

约定好了数据的组织方式,那MySQL的作用不就是:按照约定数据规则将数据文件中的数据加载进内存,然后展示给用户看,以及提供其他能力吗?

4

数据页分裂问题

说起数据页免不了会牵扯到页分裂到问题,下面一起看一下。

假设你现在已经有两个数据页了。并且你正在往第二个数据页中写数据。

关于B Tree,你肯定知道B Tree中的叶子结点之间是通过双向链表关联起来的。

在InnoDB索引的设定中,要求主键索引是递增的,这样在构建索引树的时候才更加方便。你可以脑补一下。如果按1、2、3...递增的顺序给你这些数。是不是很方便的构建一棵树。然后你可以自由自在的在这棵树上玩二分查找。

那假设你自定义了主键索引,而且你自定义的这个主键索引并不一定是自增的。

那就有可能出现下面这种情况 如下图:

mysql三个范式(说说什么是页分裂吧)(3)

假设上图中的id就是你自定义的不会自增的主键

然后随着你将数据写入。就导致后一个数据页中的所有行并不一定比前一个数据页中的行的id大。

这时就会触发页分裂的逻辑。

页分裂的目的就是保证:后一个数据页中的所有行主键值比前一个数据页中主键值大。

经过分裂调整,可以得到下面的这张图。

mysql三个范式(说说什么是页分裂吧)(4)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页