4.数据结构-B+tree与MySql

上篇我们研究了B树的特点,或多或少的介绍了B树与mysql的关系,在mysql实际的数据结构使用的并不是B树而是B+tree。下面我们就侧重介绍什么是B+tree,他和B-tree有什么相似点和不同的地方,以及B+tree和mysql的关系。

一、介绍B+tree先介绍下mysql数据存储结构

mysql数据结构数据结构优势数据结构劣势时间复杂度适用场景支持的数据类型
B+tree磁盘友好,性能好数据结构复杂O(n)=O(logmN)mysql查询的大部分场景全支持
Hash性能优越,数据结构简单支持场景少O(n)=O(1)只支持=、in、not in等,不支持范围查找,B+tree磁盘更友好的算法,hash使用场景比较单一,其时间复杂度非常高O(n)=O(1)支持但是无法控制
Rtree适合地理位置查询场景特殊场景使用 只支持范围查询,mysql做地理位置查询geometry
全文索引模糊查询场景性能高需要额外分词浪费磁盘空间O(n)=O(n)全文收索char、varchar、text

 

二、B+tree是什么

B+ 树是一种树数据结构,通常用于数据库和操作系统的文件系统中。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入,这与二叉树恰好相反。B+ 树在节点访问时间远远超过节点内部访问时间的时候,比可作为替代的实现有着实在的优势。这通常在多数节点在次级存储比如硬盘中的时候出现。通过最大化在每个内部节点内的子节点的数目减少树的高度,平衡操作不经常发生,而且效率增加了。这种价值得以确立通常需要每个节点在次级存储中占据完整的磁盘块或近似的大小

 4阶(2,5)B+tree

 

三、B+tree定义

B+tree是一种 叶子节点收尾相连双向链表、且data节点只在叶子节点的 的B-tree结构  

 

四、B+tree性质 

前提:一个 m 阶的B树

      1.每一个节点最多有 m 个子节点

      2.每一个非叶子节点(除根节点)子节点数范围 ⌈m/2,m⌉ (ps:小数情况m/2的值向下取整)

      3.如果根节点不是叶子节点,那么它至少有两个子节点

      4.有 n个子节点的非叶子节点拥有n−1个键 (ps:上图3阶树,共计2个数据关键词)

      5.所有的叶子节点都在同一层 (ps:既根节点到每个叶子节点的路径相等)

      6. 叶子节点data首尾相连成为一条链

   PS:B+tree的阶是指B-tree节点的指针数目

 

五、B+tree特点

  1. B+tree是一种平衡树 [B-tree的自下而上的构建方式保证]
  2. 根节点至少有2个子节点
  3. 关键词数目等于n个子节点的数目减一,因为Btree的结构是2个子节点夹一个关键词
  4. B+tree关键词排序,从左到右升序排列
  5. B+tree遍历到叶子节点后,会继续遍历其叶子节点尾部的节点上面的关键词

 

六、B+tree查找遍历

  • B+Tree IO方式   

  1. 由于数据库索引可能很大,不可能常驻内存,所以索引会以文件的形式存在硬盘中。
  2. B+tree遍历方式是先序遍历,应为先序遍历B+Tree的时间复杂度更低,其好处在上篇文章已经说明。
  3. MySql在非叶子节点每确定一次层高数据范围做一次IO。
  4. 由于B+tree的遍历方式是,左data节点遍历完毕后会通过节点指针到右侧节点继续遍历,受制于系统内存大小和Linux的page size,怀疑mysql在叶子data节点查询的时候会继续IO。【此处待研究mysql后在确认】但是B+tree在算法上还是要比B-tree IO的次数更少。

 

七、B+tree如何保证结构稳定平衡

B树的构建方式是自下而上的构建方式,二叉树和红黑树是自上而下的构建方式,B树这种构建方式好处在于树结构稳定平衡性很强,不容易发生树平衡。以mysql为案例,其开启16k的页缓存,当索引字段大小为8k,如果树高为3,其支撑最大的索引数目为2048*2048*2048+2048*2048+2048 > 85亿。

 

八、B+tree总结

  • B+tree为什么使用多阶?

         多阶好处:

               多阶的好处是降低树的高度,在查询的时候很快定位到目标数,多阶的设计也符合现在磁盘系统读取数据的方式,现在磁盘系统取数据不是取的目标数据,磁盘取数据按照页大小取所需要的磁盘物理单元,具体流程参考我以前文章[IO流程简介] ,B-tree的结构就是一种多阶的红黑树,这种设计使得树的平衡性好,且时间复杂度比较高效O(n)=logmN。    

         多阶坏处:

              多阶坏处,实现难度大特别是B-tree的平衡部分。B-tree在平衡的时候可能整颗树都会导致再次平衡,如何做到高效的平衡?待研究

  • MySql中B+tree的最佳遍历方案是先序遍历吗?

       由于mysql是通过关键词查询记录,原理是B+tree通过根节点的阶逐步定位到树的读,然后查询到目标范围。这种模式对于B+tree查询到关键词的过程采用先序遍历(先序遍历、中序遍历、后序遍历)是最高效的遍历方案,其时间复杂度O(n)=logmN  。故mysql查询索引的顺序是从左到右。

 

  • B+tree为什么叶子节点首尾相连?

        叶子节点收尾相连原因是因为B树的排序是按照小大,从左到右的顺序排序的原因,有这个条件B+tree直接从左到有遍历叶子节点就会节省在次从根部节点去遍历定位数据,相当于降低算法复杂度。

九、MySQL 聚集索引VS辅助索引

       MySQL索引分为聚集索引和辅助索引,两者的区别是聚集索引携带的是有序的数据,二辅助索引存放的是数据位置的指针,由于mysql联合索引主索引是(聚集索引),所以MySQL查询都必须带上主索引。

  • 聚集索引

        InnoDB存储引擎表是索引组织表,即表中数据按照主键顺序存放。而聚集索引(clustered index)就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树数据结构一样,每个数据页都通过一个双向链表来进行链接。由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。由于定义了数据的逻辑顺序,聚集索引能够特别快地访问针对范围值的查询。

  • 辅助索引

        辅助索引(Secondary Index,也称为非聚集索引),叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签(bookmark)。该书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。书签就是相应行数据的聚集索引键(主键)。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后再通过主键索引来找到一个完整的行记录。

 

十、MySql索引与B+tree问与答

  • 问题一、MySql联合索引数据结构与最左原则

       MySql联合索引数据结构

联合索引B+Tree数据结构,淡黄色的为主索引,粉红色的为联合索引

     Myql联合索引特点

     联合索引如果索引生效必须带上主索引(聚集索引),而联合索引(辅助索引)的部分就是在主索引数据筛选的基础上再次筛选。比如下图a,b,c构成test表的联合索引  索引覆盖:a,b,c、a,c、a,b   索引不覆盖:b,c、c,b

 

联合索引结构 a,b,c构成联合索引

 

a,b,c查询走索引

 

a,c查询走索引

 

b,c查询不走索引

 

   MySql为什么具有最左原则     

   B+Tree也是一种树结构的数据结构,是树结构其遍历方式分别为 先序遍历、中序遍历、后续遍历三种遍历方式。其中先序遍历的原则是根左右,这种遍历的方式树查询效率最高时间复杂度O(n)=logmN(m底数:阶数目,N待查询数总数),故MySql采用先序遍历的方式遍历。所以也就有了MySql的最左原则。   

  • 问题二、B+tree节点与mysql Page的关系

       B树节点就是一个物理Page(16K)数据按16KB切片为Page 并编号 编号可映射到物理文件偏移(16K * N) B+树叶子节点前后形成双向链表

  • mysql页查看

mysql> show variables like 'innodb_page_size';
  • 问题三、MySql索引存在在哪里?

         内存或者硬盘  [存放目录:mysql-5.7.19/data/pay2 *.myi 文件]     

  • 问题四、mysql聚合统计与B+tree

         待研究

  • 问题五、mysql分组与B+tree

        待研究

  • 问题六、mysql排序与B+tree

        待研究

  • 问题七、MySql B+tree树高推导过程

       推导mysql B+tree树高前,先推导mysql的阶。mysql的阶和两个因素有关系,第一个因素是mysql page size大小 4k、8k、16k(默认16k),第二个因素是索引字段大小。M(阶)=Page Size/字段大小。下面介绍树高其和B+tree阶(m)和索引总数据(N)有关系,推导公式 h=LogmN。

  • 问题八、为什么索引影响MySql的插入性能

        因为字段有索引的情况下,插入删除数据会维护索引,导致浪费一部分资源

  • 问题九、为什么?like 'xx%'走索引,like'xx%'  和 like '%xx%'不走索引

       mysql索引最左原则

  • 问题十、为什么MySql不使用B树而使用B+树

       Mysql要保证区间访问的性能,由于MySql的数据关联性强,B数适合查询单个文档的场景。B树的优势是目标节点自带data节点,而不是只有叶子节点带data节点降低IO次数。B+树只有叶子节点带date节点,但是节点双向链表相连对于范围关系等场景场景更适合。

 

B+tree代码实现

       git实现地址【目前未实现,待更新】   

 

参考及推荐文档

      1. mysql InnoDB引擎支持hash索引吗

      2.Innodb页概念

      3.InnoDB的行记录格式, Compact, Redundant, Compressed, Dynamic

      4.InnoDB的行溢出数据,Char的行结构存储

      5.MySQL系列:innodb源码分析之page结构解析

      6.INNODB 数据页结构

      7.innodb page重组空间压缩函数(btr_page_reorganize_low)注释

      8.MySQL · 引擎特性 · InnoDB 文件系统之文件物理结构

      9.MySQL 如何存储长度较大的varchar与blob

      10.InnoDB 逻辑存储结构

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值