文章公号 首发!连载中~ 欢迎各位大佬关注, 回复:“抽奖” 还可参加抽📖活动 html
文末有二维码 mysql
回顾一下以前和你们分享的知识点golang
看了前面的文章,想必你确定了解了什么是Buffer Pool、LRU-List、Free-List、Flush-List,你也知道了当MySQL增删改查时,内存中发生了什么,以及这几个双向链表是如何配合工做的。面试
经过阅读上一篇文章你也必定了解了:你create出来的table实际上是属于一个表空间的,而所谓的表空间其实对应着一个真实存在于物理磁盘上的文件。sql
而且在前面的文章中,白日梦曾不止一次的说起到:InnoDB从磁盘中读取数据的最小单位是数据页。而你想获得的id = xxx的数据,就是这个数据页众多行中的一行。数据库
下面咱们就一块儿看下,究竟什么是MySQL的数据页、数据区等概念。缓存
数据页长下面这样:优化
在MySQL的设定中,同一个表空间内的一组连续的数据页为一个extent(区),默认区的大小为1MB,页的大小为16KB。16*64=1024,也就是说一个区里面会有64个连续的数据页。连续的256个数据区为一组数据区。3d
因而咱们能够画出这张图:htm
从直观上看,其实不用纳闷为啥MySQL按照这样的方式组织存储在磁盘上的数据。
这就比如你搞了个Java的封装类描述一类东西,而后再相应的给它加上一些功能方法,或者用golang封装struct去描述一类对象。最终的目的都是为了方便、管理、控制。
约定好了数据的组织方式,那MySQL的做用不就是:按照约定数据规则将数据文件中的数据加载进内存,而后展现给用户看,以及提供其余能力吗?
假设你如今已经有两个数据页了。而且你正在往第二个数据页中写数据。
关于B+Tree,你确定知道B+Tree中的叶子结点之间是经过双向链表关联起来的。
在InnoDB索引的设定中,要求主键索引是递增的,这样在构建索引树的时候才更加方便。你能够脑补一下。若是按一、二、3...递增的顺序给你这些数。是否是很方便的构建一棵树。而后你能够自由自在的在这棵树上玩二分查找。
那假设你自定义了主键索引,并且你自定义的这个主键索引并不必定是自增的。
那就有可能出现下面这种状况 以下图:
假设上图中的id就是你自定义的不会自增的主键
而后随着你将数据写入。就致使后一个数据页中的全部行并不必定比前一个数据页中的行的id大。
这时就会触发页分裂的逻辑。
页分裂的目的就是保证:后一个数据页中的全部行主键值比前一个数据页中主键值大。
通过分裂调整,能够获得下面的这张图。
参考:
https://dev.mysql.com/doc/refman/5.7/en/glossary.html
面试官都关注了!你还在犹豫什么呢?