MySQL数据库——索引结构之B+树

本文先介绍数据结构中树的演化过程,之后介绍为什么MySQL数据库选择了B+树作为索引结构。

在这里插入图片描述

文章目录

      • 树的演化
      • 为什么其他树结构不行?
        • 为什么不使用二叉查找树(BST)?
        • 为什么不使用平衡二叉树(AVL树)?
        • 为什么不使用B树?
      • 为什么选择 B+ 树
        • 1. B+ 树节点结构
        • 2. 优点
        • 举例
      • Q&A
        • Hash比B+树更快,为什么Mysql用B+树来存储索引呢?
        • 增加树的路数可以降低树的高度,那么无限增加树的路数是不是可以有最优的查找效率?

树的演化

    • 非线性结构,每个节点有唯一的一个父结点和多个子结点(子树),为一对多的关系。
  1. 二叉树

    • 每个结点最多有两颗子树,并且子树有左右之分,不能颠倒。
  2. 满二叉树

    • 每一层的结点个数都达到了当层能达到的最大结点数。
  3. 完全二叉树

    • 除了最下面一层之外,其余层的结点个数都达到了当层能达到的最大结点数,且最下面一层只从左至右连续存在若干结点,右边的结点全部不存在。
  4. 二叉查找树 (BST)

    • 又称为二叉排序树、二叉搜索树。
    • 定义:
      1. 要么二叉査找树是一棵空树。
      2. 要么二叉查找树由根结点、左子树、右子树组成,其中左子树和右子树都是二叉查找树,其中:
        • 左子树的所有结点值小于或等于根节点值
        • 右子树的所有结点值大于根节点值。
  5. 平衡二叉树 (AVL 树)

    • 特殊的二叉查找树,左右子树都是平衡二叉树,且左右子树高度之差不超过 1。
  6. B 树

    • 又名平衡多路查找树。每个节点包含多个数据及指针域,查找路径有多个分支。B-树就是 B 树(别讲什么B减树,‘-’是分隔符)。
  7. B+ 树
    在 B 树基础上发展而来的平衡多路查找树,非叶子节点只存储键值和指针,所有数据存储在叶子节点,并通过链表连接。
    优化主要体现在以下几个方面:

    1. 非叶子节点不存储数据,更适合磁盘存储和 I/O 优化
      • B 树:所有节点都存储键值和数据。
      • B+ 树:非叶子节点只存储键值和指针,不存储实际数据,使得内部非叶子节点更小,单个磁盘块可容纳更多键值,减少树的高度和磁盘 I/O 次数,降低树的高度。
    2. 叶子节点存储所有数据,更便于顺序遍历,查找效率稳定
      • B 树:数据分散在各个节点,遍历需要中序遍历整棵树。 查询可能在任何节点结束,查询效率不稳定。
      • B+ 树:所有数据存储在叶子节点,并通过链表连接,范围查询、排序查询更高效,可以快速顺序遍历数据,无需回溯,所有查询最终都在叶子节点结束,查找效率稳定。

为什么其他树结构不行?

磁盘读写的特性

  1. 数据库的索引及数据存储在磁盘中,而不是内存中,磁盘 I/O 的速度远慢于内存。
  2. 从磁盘读取数据时,按照磁盘块(页)读取,每次读取的最小单位是一个磁盘块。
  3. 若能将更多数据放入一个磁盘块中,一次读取操作可以获取更多数据,从而减少 I/O 次数,提高查询效率
为什么不使用二叉查找树(BST)?
  • 可能出现链表形态:二叉查找树在数据不平衡时可能退化成一条链表,类似于全表扫描,查找时无法发挥二叉排序树的优势。
  • 高度过高:树的高度过高时,查找效率变得不稳定,查询需要遍历较多的节点,导致性能下降。
为什么不使用平衡二叉树(AVL树)?

平衡二叉树通过自平衡解决了BST高度过高,查找效率不稳定的问题。但是:

  • 节点存储限制:平衡二叉树每个节点只能存储一个键值和数据,对于海量数据,节点数量会非常多,树的高度依然可能较高。
  • 效率降低:对于大量数据的存储和查找效率依然不理想,因为节点存储量有限,高度无法有效缩减。
为什么不使用B树?

B树每个节点有更多子节点,减少了树的高度,从而提高了IO性能。解决了平衡二叉树只能存储一个键值和数据的问题。但是:

  • 遍历效率低:尽管B树提高了IO性能,但在查找数据时,仍然需要遍历整个树,导致遍历效率低,不同的点查询效率不一样,即查询效率不稳定。

为什么选择 B+ 树

在这里插入图片描述

  • 二叉查找树:可能退化为链表,查找效率不稳定。
  • 平衡二叉树:虽然能保证平衡,但对于海量数据,节点数仍多,高度过高。
  • B树:提高了IO性能,解决了平衡二叉树的问题,但遍历效率不足,特别是对于大范围查询。

引入B+树:为了进一步提高遍历效率,B+树在B树的基础上做了优化:

1. B+ 树节点结构
  • 非叶子节点仅存储键值,不存储数据,节点更紧凑。
  • 数据只存储在叶子节点,叶子节点通过双向链表串联形成线性表。查询时只需要扫描叶子节点,从而大幅提高了范围查询和排序查询的效率。
  • 数据库页的大小固定(如 InnoDB 默认 16KB),更高阶数的树更矮更胖,减少了磁盘 I/O 次数。
2. 优点
  1. 磁盘读写代价更低

    • 内部节点不存储数据,节点更小,单个磁盘块可容纳更多键值。
    • 减少树的高度,相同数据量下 I/O 次数更少。
  2. 查询效率更加稳定

    • 查询路径固定,从根节点到叶子节点的路径长度一致,每次查询效率相同。
  3. 更便于遍历

    • 数据全部存储在叶子节点,顺序遍历时只需扫描叶子节点即可。
    • 非叶子节点均为索引,便于范围查询和排序。
  4. 更适合范围查询

    • 叶子节点通过链表连接,直接支持高效的范围查询和排序操作。
    • 在数据库中,基于范围的查询非常频繁,而 B 树不支持或效率较低。

举例

磁盘页大小:默认是 16 KB,也就是16,384 字节(1 KB = 1024 字节)。
假设条件:
2. 每个键值的大小:假设每个键值的大小是 16 字节。
3. 每个节点存储的键值数量:每个磁盘页可以存储 1024 个键值。

  • 如果一个节点可以存储 1000 个键值时(没有超过1024 个键值),3 层的 B+ 树可以存储约 10 亿条数据。
  • 根节点常驻内存,那么查找 10 亿条数据时只需 2 次磁盘 I/O。

Q&A

Hash比B+树更快,为什么Mysql用B+树来存储索引呢?

首先在功能上:

  • B+树可以进行BETWEEN范围查询,Hash索引不能。
  • B+树支持order by排序,Hash索引不支持。
  • B+树使用like 进行模糊查询的时候,like后面(比如%开头)的话可以起到优化的作用,Hash索引根本无法进行模糊查询。
  • B+树支持 InnoDBMyISAMMemory,Hash索引仅支持Memory(默认情况)
  • B+树支持联合索引的最左侧原则,Hash索引不支持。
  • Hash索引在等值查询上比B+树效率更高。

从设计上来看:

  • 从内存角度上说,数据库中的索引一般时在磁盘上,数据量大的情况可能无法一次性装入内存,B+树的设计可以允许数据分批加载
  • 从业务场景上说,等值查询那确实是hash更快,但是数据库中经常会进行排序和范围查询,B+树叶子节点通过双向链表串联形成线性表,它的查询效率比hash就快很多了,hash还需要解决冲突。
增加树的路数可以降低树的高度,那么无限增加树的路数是不是可以有最优的查找效率?

答:这样会形成一个有序数组,文件系统和数据库的索引都是存在硬盘上的,并且如果数据量大的话,不一定能一次性加载到内存中。有序数组没法一次性加载进内存,这时候B+树的多路存储威力就出来了,可以每次加载B+树的一个结点,然后一步步往下找。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/497885.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外网访问 Docker 容器的可视化管理工具 DockerUI

DockerUI 是一个 docker 容器镜像的可视化图形化管理工具,DockerUI 可以用来轻松构建、管理和维护 docker 环境。让用户维护起来更方便。 本文就介绍如何安装使用 DockerUI 并结合路由侠内网穿透来访问 DockerUI。 第一步,安装 DockerUI 1,…

「Mac畅玩鸿蒙与硬件48」UI互动应用篇25 - 简易购物车功能实现

本篇教程将带你实现一个简易购物车功能。通过使用接口定义商品结构,我们将创建一个动态购物车,支持商品的添加、移除以及实时总价计算。 关键词 UI互动应用接口定义购物车功能动态计算商品管理列表操作 一、功能说明 简易购物车功能包含以下交互&#…

19、鸿蒙学习——配置HDC命令 环境变量

一、下载Command Line Tools 可参考上篇《鸿蒙学习——配置OHPM、hvigor环境变量》 二、配置hdc环境变量 hdc命令行工具用于HarmonyOS应用/元服务调试所需的工具,该工具存放在命令行工具自带的sdk下的toolchains目录中。为方便使用hdc命令行工具,请将…

linux学习笔记(一).学习路径+学习流程+起源

背景 再跟着尚硅谷视频Linux教程(1>7)学习linux,日常做笔记督促自己学习。 Linux学习笔记 Linux应用领域 1.个人桌面应用领域 能力一般 2.服务器应用领域 强项 3.嵌入式应用领域 强项 Linux学习流程 基础 1.基本命令操作(文件命令操作copy等等&#xf…

LeetCode每日三题(六)数组

一、最大子数组和 自己答案: class Solution {public int maxSubArray(int[] nums) {int begin0;int end0;if(numsnull){//如果数组非空return 0;}else if(nums.length1){//如果数组只有一个元素return nums[0];}//初值选为数组的第一个值int resultnums[0];int i…

Linux Debian安装ClamAV和命令行扫描病毒方法,以及用Linux Shell编写了一个批量扫描病毒的脚本

ClamAV是一个开源的跨平台病毒扫描引擎,用于检测恶意软件、病毒、木马等安全威胁。 一、Linux Debian安装ClamAV 在Linux Debian系统上安装ClamAV,你可以按照以下步骤进行: 更新软件包列表: 打开终端并更新你的软件包列表&#…

VSCode outline显示异常的解决方法——清除VSCode的配置和用户文件

1. 删除所有配置文件 sudo apt remove --purge code2. 删除所有用户文件 rm -rf ~/.config/Code rm -rf ~/.vscode rm -rf ~/.local/share/code rm -rf ~/.cache/Code3. 重装Code sudo dpkg -i code_1.96.2-1734607745_amd64.deb如此,可修复异常导致的outline无…

Crawler实现英语单词的翻译

首先声明一点,这种方法仅限于低频次的交互来获取翻译信息,一旦一秒内大量的请求会被重定向,那就直接不能用了 如果希望可以批量查询英语单词翻译,可以查看我的下一篇博客。 接下来的任务就是要把这么一大堆的单词进行翻译&#xf…

QT 学习第十四天 QWidget布局

QT 学习十四天 布局 布局管理Qt Widgets 布局布局管理器简介基本布局管理器栅格布局管理器窗体布局管理器综合使用布局管理器设置部件大小可扩展窗口 布局管理 今天讲 Qt Widgets 和 Qt Quick 中的布局。 前者主要用布局管理器 后者除了布局管理器还有基于锚的布局&#xff08…

jangow靶机

打开靶机,打开kali,有的人会发现扫不到靶机的ip 在网上搜索了半天,发现是靶机的网卡配置有问题 重启靶机,选第二个 进去后再选第二个,按e 找到ro这一行 把ro后面这一行的内容都替换成ro rw signin init/bin/bash ctr…

redis开发与运维-redis0401-补充-redis流水线与Jedis执行流水线

文章目录 【README】【1】redis流水线Pipeline【1.1】redis流水线概念【1.2】redis流水线性能测试【1.2.1】使用流水线与未使用流水线的性能对比【1.2.2】使用流水线与redis原生批量命令的性能对比【1.2.3】流水线缺点 【1.3】Jedis客户端执行流水线【1.3.1】Jedis客户端执行流…

KOI技术-事件驱动编程(Sping后端)

1 “你日渐平庸,甘于平庸,将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的,那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人,和他们斗了那么久,最终却要变得和他们一样,…

小程序配置文件 —— 14 全局配置 - tabbar配置

全局配置 - tabBar配置 tabBar 字段:定义小程序顶部、底部 tab 栏,用以实现页面之间的快速切换;可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面; 在上面图中,标注了一些 tabBar …

小程序基础 —— 08 文件和目录结构

文件和目录结构 一个完整的小程序项目由两部分组成:主体文件、页面文件: 主体文件:全局文件,能够作用于整个小程序,影响小程序的每个页面,主体文件必须放到项目的根目录下; 主体文件由三部分组…

使用ArcGIS/ArcGIS pro绘制六边形/三角形/菱形渔网图

在做一些尺度分析时,经常会涉及到对研究区构建不同尺度的渔网进行分析,渔网的形状通常为规则四边形。构建渔网的方法也很简单,使用ArcGIS/ArcGIS Pro工具箱中的【创建渔网/CreateFishnet】工具来构建。但如果想构建其他形状渔网进行相关分析&…

【K8S问题系列 | 21 】K8S中如果PV处于Bound状态,如何删除?【已解决】

在Kubernetes(K8S)的存储管理体系中,持久卷(PersistentVolume,PV)是一种重要的资源,它为Pod提供了持久化存储能力。当PV处于Bound状态时,意味着它已经与某个持久卷声明(P…

旅游管理系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

Qt5 中 QGroupBox 标题下沉问题解决

我们设置了QGroupBox 样式之后,发现标题下沉了,那么如何解决呢? QGroupBox {font: 12pt "微软雅黑";color:white;border:1px solid white;border-radius:6px; } 解决后的效果 下面是解决方法: QGroupBox {font: 12pt "微软雅黑";color:white;bo…

六大基础深度神经网络之CNN

左侧是传统卷积网络输入的是一列像素点,右侧是卷积神经网络,输入的是具有长宽通道数的原始图像 下图为整体架构。卷积层可以认为提取特征,池化层是压缩特征。全连接层是把图像展平然后计算10个类别的概率值 给出一张图像不同区域的特征不同&a…

抽象工厂设计模式的理解和实践

在软件开发中,设计模式是前人通过大量实践总结出的、可复用的、解决特定问题的设计方案。它们为我们提供了一种标准化的解决方案,使得代码更加简洁、灵活和易于维护。在众多设计模式中,抽象工厂模式(Abstract Factory Pattern&…