• B树和B+树 为什么B+树更适合mysql


    B+树Java代码实现以及测试

    B树和B+树的区别

    节点构造

    通过实现B树和B+树
    B+树 代码
    B树 代码

    B-树内部节点是保存数据的;而B+树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。

    B+树 代码
    B树 代码

    根据链接的代码我们可以了解到一个节点:

    B-树: 保存Entry数据项以及子树指针。
    B+树: 保存关键字以及子树指针。

    B+树 代码链接中的Java代码还是有部分缺陷的。

    B+树相比与B树的一个重要特性就是它的内部节点不存储数据,只保存关键字信息用于索引。

    如果数据仅仅为一个值key,B+树的优势就只有可以范围查询了(下文介绍),并且因为数据冗余存储花销大于B树。
    在这里插入图片描述
    在这里插入图片描述

    但是如果存储的数据很大,我们以mysql索引为例,通过B+树存储数据,一行数据中,一般都有一个键,以及其他附属的列,称为值,那么这个键值对关系就比较明确了。

    B+树构造索引:内部节点仅存放键,叶子节点存放所有的行数据信息。这时B+树相对于B树的优势就展现出来了。

    优势一: B+树查找更快+mysql预读特性

    为什么?

    因为以下两个特性:

    1.  B+树内部节点不存储真实数据,将真实数据放到叶节点
    
    • 1

    使用B+树构造索引,它的内部节点定义可以是这样:

    https://www.codeleading.com/article/13672521751/ 参考

    private class BPlusTreeNode{
    		int nodeTotal=0;                                  // "Max" = 5 ; 记录本节点个数
    		int[] values=new int[MaxOrder];                   // 用于存储主键元素
    		BPlusTreeNode[] children=new BPlusTreeNode[MaxOrder];
    
    • 1
    • 2
    • 3
    • 4

    而使用B树构造索引,它的内部节点会是这样:

    private class BTreeNode{
    		int nodeTotal=0;                                  // "Max" = 5 ; 记录本节点个数
    		private List<Entry<K, V>> entrys;				//存储数据项
    		BTreeNode[] children=new BTreeNode[MaxOrder];
    
    • 1
    • 2
    • 3
    • 4

    对于B树来说,一个Entry的大小取决于数据的大小,如果存储的行数据很大,那么B树每个节点需要存储的数据项占用空间也会很大,但是B+树不会,它完全可以只保存一个int数组来存放行数据的主键信息用于索引就好了,将真实数据放到叶节点存储。

    2. 顺序读取和局部性原理
    
    • 1

    可以直接说明,mysql的索引存放于表空间,每一个节点可以认为是一个块(页面),从内存中读取索引时顺序读取时常常会预读取(额外读取后面的连续块)。

    提问:这个时候是不是需要追求对整个索引一次读取到的越多越好?

    当然,如果一次能够读取到整个索引,就不需要二次IO了。

    这就是上面特性一:B+树内部节点不存储真实数据,将真实数据放到叶节点的好处。

    因为B+树内部节点不存储真实数据,将真实数据放到叶节点,所以索引的内部节点占用空间更少,一次IO读取到的信息更多,定位满足条件的数据行就会更快。

    优势二:B+树面向修改更快

    还是根据特性一:B+树内部节点不存储真实数据,将真实数据放到叶节点

    我们知道一个树结构它的插入和删除操作可能会对整棵树的结构产生影响,比如分裂、换位等等,如果节点又过于臃肿,那么插入和删除会花销很大,相反如果节点存储的数据很少,就会减少这个花销。

    B+树因为特性一所以它的修改和删除的花销相比于使用B树会小一些。

    优势三(比较重要的优势) B+树可以实现范围查找

    其他优势都属于性能优势,如果你可以容忍部分性能损失,使用B树也可以,而这个优势是B+树契合于数据库索引的重要原因,是B树所无法替代的。

    所有叶子都在相同的高度上,叶结点本身按关键字大小从小到大链接。
    
    • 1

    mysql官网

    innodb实现叶子节点之间产生连接,所以我们通常说innodb通过B+树来实现。

    所以我们在这里谈B树和B+树只是在谈标准的B树和B+树特性,真正在使用过程并不一定就是严格的、我们通常理解的B+树。
    B+树 代码中也表达了这一困惑,其实也说明我们通常定义的标准数据结构并非一定要在使用中采用,而是根据应用灵活改变。

    在这里插入图片描述

    索引为什么使用B+树?

    通过上面的分析这个答案应该已经明确了。但是需要说明,B+树比B树更适合做索引仅仅是因为更契合数据库索引的使用场景。B+树和B树没有优劣一说,二者根据不同的场景可以发挥不同的优势。

    这是一种非常重要的思想,使用数据结构一般从三个方面考量:

    • 业务场景(mysql使用了预读场景,B+树更合适,数据库一般处理的数据量极大,B+树内部节点不保存真实数据查询效率、修改效率都会更好。)
    • 功能要求(范围查询,B+树可以做到)
    • 性能要求 (在脱离业务场景下,显然B树的查询效率更高。但是因为业务场景的加持,这一点性能要求是随着业务场景的变化而变化的。此时的B+树比B树更好。)
  • 相关阅读:
    【matlab】如何批量修改图片命名
    【Python小项目之Tkinter应用】随机点名/抽奖工具大优化:实现背景图与其他组件自适应窗口大小变化并保持相对位置和比例不变
    PHP对接api时,如何保证其安全性
    我们怎样制作照片拼图?简单实用的拼图方法来了
    NFT Marketplace 比较 | 快速指南
    【面试必问】HTTP与HTTPS的区别以及HTTPS的工作流程
    ESP32S3的ESP_LOGx()控制台输出详细介绍
    人工智能、深度学习、机器学习书目推荐
    Netty客户端与服务器端闲暇检测与心跳检测(三)
    【周赛复盘】力扣第 85 场双周赛
  • 原文地址:https://blog.csdn.net/qq_44587855/article/details/124750712