MYSQL(上)

一、底层数据结构-页(Page)

为了避免一条一条读取磁盘数据(IO操作频繁),减少磁盘与内存交互的成本,InnoDB采取页的方式,作为磁盘与内存交互的基本单位,基本大小一般为16KB。InnoDB为了不同的目的设计了不同类型的页,eg:存放表空间头部信息的页、存放undo日志信息的页、存放表中数据记录的页(索引页、数据页)。

1、InnoDB数据页结构(User Record 与Free Space此消彼长关系):
数据页结构
不同阶段页的结构:
不同阶段页的结构
2、记录(可以理解为插入的数据)的头信息
单条记录的存储结构
1>deteled_flag(逻辑删除)
删除操作:把deteled_flag=1;
将删除的记录,组成一个垃圾链表(目的:空间可重用)。
不直接采用物理删除的原因是减少性能消耗。
2>min_rec_flag
B+树种每层非叶子节点中标识最小目录项记录。
3>n_owned
将一个页划分为若干个组,一个组里的主键最大的保存该值,该值标识一个组里面有多少条记录。
4>heap_no(堆号)
每条插入的的记录都会分配堆号,从2开始(InnoDB默认该页最小值Infimum heap_no = 0,该页最大值Supremum heap_no = 1)。
5>record_type(记录类型)
0 普通记录
1 B+树非叶子节点目录项记录(叶子节点存放数据为普通记录)
2 表示最小值的记录
3 表示最大值的记录
6>next_record(下一条记录)
从当前记录的真是数据指向效益条记录的真实数据。位置如下图:
指向位置

指向该位置的原因:向前可查询记录的额外信息,向后可查询记录的真实数据。
3、Page Directory
记录在页中的体现,存储方式为组,使用槽号去快速标识。
记录在页中的体现

1>最底层记录的特点:
按照主键从小到大依次排序;单向链表。
2>分组规则
对于页中最小记录只能有一条,即自己;
对于页中最大记录,阻力只能有1-8条记录;
对于其他记录阻力只能有4-8条。
3>分组步骤
最初,无记录,一个新的数据页分为两个组,Infimum组一条记录,Supremum组一条记录;
之后,插入记录到Supremum组,n_owned +1;
最后,Supremum组满,进行拆分为4+5两个组,申请新的槽位号。
4>页中的删除操作
页中的删除操作
5>页满后的插入操作,插入分页时也会保证主键的排序
页满后的插入操作
实际操作中为了避免因保证主键有序而产生的数据迁移操作,可采用增加一个自增的列作为主键的方法。

二、索引(Index)

1、B树和B+树
在单页中进行某条数据查询时,使用槽位号根据最大值最小值二分法,再单项遍历去查询,那涉及到多个页时怎么办呢,这时就要涉及到B+树。
B树和B+树

B树和B+树的区别(引自https://www.cnblogs.com/nullzx/p/8729425.html):
B树
B+树

2、索引
引用B+树结构,叶子节点存储完整的数据页,非叶子节点存储页目录项(包含页的最大值和最小值)
,搜索时也按照二分法去查找。
1>聚 簇 索 引(主键索引)聚簇索引

2>二级索引:查找到二级索引后再根据主键索引去回表查询
二级索引
3>联合索引(二级索引的一种),与二级索引的区别在于多列,会默认有个排序的列索引,查找方式为:先根据排序的列索引去查找,再去查找另外一列,如果不按照排序的列索引去查找,只能一个个去查找。如果索隐列无法确定一个目录项,则会默认添加主键索引。
联合索引
目录项记录的唯一性

三、缓冲池(Buffer-Pool)

索引–>数据–>页–>磁盘。每次查询都要把该记录所在的页里的所有记录都加载,若查询的记录不在同一个页中,那需要加载更多的记录,会产生大量的IO操作。磁盘与内存交互会限制查询速度,为加快交互,引入缓冲池。
缓冲池概述:
缓冲池概述
1>free链表:控制块的双向链表,决定是否还有空间去插入缓冲页
free链表
2>flush链表:存放被修改的缓冲页(脏页)对应的控制块
flush链表
什么时候会将脏页刷新到磁盘?
A:
BUF_FLUSH_LIST:从flush链表中刷新一部分脏页到磁盘,后台有线程的情况下,根据系统繁忙程度确定刷新速率。
BUF_FLUSH_SINGLE_PAGE:系统很繁忙,导致刷新脏页的速率很低,没有可用的缓冲页,就会去查看LRU链表尾部,看是否存在可以直接被释放的没有被修改的缓冲页,如果没有,则不得不将LRU链表尾部的一个脏页刷新到磁盘中。
BUF_FLUSH_LRU:从LRU链表的冷数据刷新一部分页面到磁盘。

3>LRU链表:控制块的双向链表,解决预读和全表扫描问题
预读:
线性预读–>顺序访问读取当前区读取超过56个,预读下个区全部页;
随机预读–>当前区13个连续的页被加载,预读加载当前区所有页(该功能默认不开启)。
全表扫描:
查询时未加条件或未加索引,都会导致全表扫描,会冲刷热数据。
LRU链表
4>缓冲池空间分配很大时,会分为多个缓冲池实例,每个事例中有多个chunk,以便在重新分配内从空间时方便拷贝。
c h u n k 和 B u ff e r实例

如有不对地方,欢迎指出,共同学习!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值