【MYSQL篇(一)】Page页&B树&B+树&INDEX索引(聚簇索引/二级索引/聚合索引)&Buffer pool缓冲池(free链表/flush链表)

Pag–页

InnoDB采取页的方式作为磁盘和内存之间交互的基本单位。一个页的大小一般是16KB。
我们把存放表中数据记录的页,称为索引页or数据页。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
 deleted_flag:逻辑删除标记(0:未删除 1:已删除 )
 min_rec_flag:B+树中每层非叶子节点中的最小的目录项记录,都会添加该标记。
 n_owned:一个页面被分若干组后,“带头大哥”用于保存组中所有的记录条数。
 heap_no:表示当前记录在页面堆中的相对位置。
 record_type:表示当前的记录类型。
① 0:普通记录
② 1: B+树非叶子节点的目录项记录
③ 2:表示Infimum记录
④ 3:表示Supremum记录
 next_record:表示下一条记录的相对位置,也就是链表。这个属性非常重要。它表示从
当前记录的真实数据到下一条记录的真实数据的距离。
Page Directory概 述
记录在页中是按照主键值从小到大的顺序串联成为一个单向链表,因此查询也只能以头节点开始逐一向后查询,但是如果数据量很大,那么性能就无法保证了。针对这个问题,InnoDB采取了图书目录的解决方案,即:PageDirectory。
分组规则如下所示:
① 对于Infimum记录所在的分组只能有1条记录。
② 对于Supremum记录所在的分组只能在1~8条记录之间。
③ 剩下的其他记录所在的分组只能在4~8条记录之间。
 分组步骤如下:
① 初始情况下,一个数据页中只有Infimum记录和Supremum记录这两条,所以分为两个组。
② 之后每当插入一条记录时,都会从页目录中找到对应记录的主键值比待插入记录的主键值大,并且差值最小的槽,然后把该槽对应的n_owned加1。
③ 当一个组中的记录数等于8时,当再插入一条记录的时候,会将组中的记录拆分成两个组(一个组中4条记录,另一个组中5条记录)。并在拆分过程中,会在Page Directory中新增一个槽,并记录这个新增分组中最大的那条记录的偏移量。
在这里插入图片描述

对于在页中查询过程总结一下:
如果我们要查询某一条记录,需要通过索引(主键索引/二级索引)确认记录是在哪一页,然后通过page directory页目录去查找所在的组slot。采用二分法确定记录所在的组,因为组中记录的是当前组的最大id值(主键值)并且页是一个是按照id值(主键值)从小到大的顺序串联成的一个单向链表,所以需要找到当前组的前一个组(组类似一个集合,不是单向链表),然后通过next_record去遍历记录所在组的所有记录就可以找到目标记录。

B树&B+树

在这里插入图片描述
B+树的特点
【与B树相同点】
 一个节点可以存储多个元素。
 与B树一样,叶子节点是有序的。
 每个节点中的元素,也都按照从小到大的顺序排列,即:左小右大。
 所有叶子节点都位于同一层,或者说根节点到每个叶子节点的高度都相同。
【与B树不同点】
 B+树的叶子节点是有单向指针的,其中:MySQL中采用的是双向指针。
 B+树的非叶子节点的元素是与叶子节点有冗余的(叶子节点是全量元素)


Index–索引

当记录越来越多,创建的页也会越来越多,如果仅通过链表方式遍历查询,性能会出现很大问题。如何解决呢? 采用B+树结构,即:叶子节点里存储完整的数据(数据页),非叶子节点存储主键索引(索引页)
在这里插入图片描述


聚簇索引
主键就是聚簇索引,修改聚簇索引其实就是修改主键。
在这里插入图片描述
非聚簇索引/二级索引–非主键
除主键外字段作为索引就是二级索引,二级索引在叶子节点上不是全量元素而是存索引值以及对应的主键值。当通过二级索引字段查询全量字段时,先通过二级索引找到记录对应的主键值,然后通过主键值聚簇索引查询到全量元素。
在这里插入图片描述
联合索引
联合索引就是多个字段同时作为索引–多列,叶子节点存作为索引的多个字段元素以及主键。会自动根据索引值按照顺序排列。当根据联合索引的字段去查询时,比如c1,c2字段作为联合索引。先查询c1索引值,再查询c2索引值,如果都没有就不存在数据。页内的记录是单向链表只能查找下一个,但是页与页之间是一个双向链表,可以查询到当前页的上一页记录。
在这里插入图片描述

Buffer pool–缓冲池

缓冲池概念
为了缓存磁盘中的页,MySQL服务器启动时就向操作系统申请了一片连续的内存空间,他们给这片内存起名为Buffer Pool(缓冲池)。默认Buffer Pool只有128M,可以在启动服务器的时候配置innodb_buffer_pool_size(单位为字节)启动项来设置自定义缓冲池大小。Buffer Pool对应的一片连续的内存被划分为若干个页面,默认也是16KB,该页面称为缓冲页。为了更好的管理Buffer Pool中的这些缓冲页,InnoDB为每个缓冲页都创建了控制块,它与缓冲页是一一对应的。
在这里插入图片描述

free链表

free链表又叫空闲链表,通过它可以知道缓冲池内有哪些缓冲页是空白的可用可分配的。
在这里插入图片描述

flush链表

flush链表存放的是脏页,如果我们修改了Buffer Pool中某个缓冲页的数据,那么它就与磁盘上的页不一致了,这样的缓冲页也被称之为脏页(dirty page)。为了性能问题,我们每次修改缓冲页后,并不着急立刻把修改刷新到磁盘上,而是将被修改过的缓冲页对应的控制块作为节点加入到这个链表中,该链表也被称为flush链表。
Flush链表刷新方式有两种:
【1】从flush链表中刷新一部分页面到磁盘
 后台线程会根据当时系统的繁忙程度确定刷新速率,定时从flush链表中刷新一部分页面到
磁盘。——即:BUF_FLUSH_LIST
 有时后台线程刷新脏页的进度比较慢,导致用户准备加载一个磁盘页到Buffer Pool中时没
有可用的缓冲页。此时,就会尝试查看LRU链表尾部,看是否存在可以直接释放掉的未修
改缓冲页。如果没有,则不得不将LRU链表尾部的一个脏页同步刷新到磁盘(与磁盘交互
是很慢的,这会降低处理用户请求的速度)。——即:BUF_FLUSH_SINGLE_PAGE
【2】从LRU链表的冷数据中刷新一部分页面到磁盘
 后台线程会定时从LRU链表的尾部开始扫描一些页面,扫描的页面数量可以通过系统变量
innodb_lru_scan_depth来指定,如果在LRU链表中发现脏页,则把它们刷新到磁盘。——
即:BUF_FLUSH_LRU
 控制块里会存储该缓冲页是否被修改的信息,所以在扫描LRU链表时,可以很轻松地获取
到某个缓冲页是否是脏页的信息。
在这里插入图片描述

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值