SQL进阶理论篇(四):索引的结构原理(B树与B+树)

文章目录

  • 简介
  • 如何评价索引的数据结构设计好坏
  • 二叉树的局限性
  • 什么是B树
  • 什么是B+树
  • 总结
  • 参考文献

简介

我们在上一节中说过,索引其实是一种数据结构,那它到底是一种什么样的数据结构呢?本节将简单介绍一下几个问题:

  • 什么样的数据结构更适合作为索引?平衡二叉树是否合适?
  • 什么是B树和B+树,为什么我们常用B+树作为索引的数据结构?

如何评价索引的数据结构设计好坏

由于索引是存放在磁盘上的,所以我们在通过索引来查找某行数据的时候,大量的时间其实是花在了磁盘的IO上。

因此,如果我们能让索引的数据结构尽量减少与磁盘的IO次数,那么就能减少查询所消耗的时间,这样的数据结构就是更好的。

二叉树的局限性

二叉树是一种高效且常见的数据检索方式。其时间复杂度为O(log2N),那么,采用二叉树作为索引的数据结构合适么?

让我们看一下最基础的二叉搜索树,假设需要搜索的数值是key:

  • 如果key大于根节点,则在右子树中进行查找;
  • 如果key小于根节点,则在左子树中进行查找;
  • 如果key等于根节点,那么就是找到了这个节点。

举个例子,(34,22,89,5,23,77,91)创造出来的二叉搜索树为:

在这里插入图片描述

最多只需要经过3次搜索,就能找到指定值。

但是存在特殊的情况,比如说以(5, 22, 23, 34, 77, 89, 91)的顺序创造出来的二分查找树为:

在这里插入图片描述

在这个树里,最多需要经过7次比较之后才能找到指定的节点。

因为第二棵树实际上已经退化成了一张链表,查找数据的时间复杂度变成了O(n)。

当然,如果使用平衡二叉搜索树的话,就可以解决这个问题,因为平衡二叉数在二分搜索树的基础上添加了约束,其约定每个节点的左子树和右子树的高度差不能超过1,即左右子树依然是平衡二叉树。

常见的平衡二叉树有很多种,比如说平衡二叉搜索树、红黑树、数堆、伸展树。平衡二叉搜索树是最早提出的一种平衡二叉树。因此我们一般说的平衡二叉树,其实就是平衡二叉搜索树,搜索时间复杂度就是 O ( l o g 2 n ) O(log_2n) O(log2n)

由于每访问一次节点就要进行一次磁盘IO操作,所以对平衡二叉搜索树来讲,一般会进行 O ( l o g 2 n + 1 ) O(log_2n+1) O(log2n+1)次IO操作。比如说一个5层的平衡二叉树,共31个节点,正常会进行5次IO操作。树的深度越大,意味着IO操作的次数就越多,就越影响整体数据查询的效率。

所以我们可以考虑下,如果将二叉树换成M叉树(M>2),是不是就可以降低树的高度了呢?比如说,同样的31个节点,使用三叉树来存储的话,树深就变成了 l o g 3 ( 31 + 1 ) log_3(31+1) log3(31+1),就是4层。

可以看到,此时树的高度降低了,当数据量足够大的时候,确实比二叉树要好一些。

什么是B树

上一小节中,我们讲到了M叉树(M>2)的表现要优于二叉树。因此一个节点应该允许有M个子节点。

B树就是这么被提出来的。B树,即Balance Tree,就是平衡的多路搜索树,它的高度远小于平衡二叉搜索树的高度。在文件系统和数据库系统中的索引结构经常使用B树来实现

B树的结构如下图:

在这里插入图片描述

可以看到,B树中每个节点最多可以包含M个子节点,而M则称为是B树的阶

同时,每个磁盘块中包括了关键字(如17/35)和子节点的指针(如P1、P2和P3)。指针数是关键字数量 + 1。

对一个100阶的B树来讲,如果有3层的话最多可以存储 ( 99 ∗ 1 + 99 ∗ 10 0 1 + 99 ∗ 10 0 2 ) = 999999 (99*1 + 99*100^1 + 99*100^2)=999999 991+991001+991002=999999,约100w的索引数据。

在存储数据相同的情况下,其高度远远低于二叉树的高度。

简单总结下,一个M阶B树(M>2)的特性:

  • 根节点的孩子节点数为[2, M]
  • 每个中间节点包含n-1个关键字和n个孩子,其中n的取值范围是[ceil(M/2),M]
  • 假设中间节点的关键字为 k 1 , k 2 , . . . . , k n − 1 k_1, k_2,....,k_{n-1} k1,k2,....,kn1,且关键字按照升序排序,即 k i < k i + 1 k_i < k_{i+1} ki<ki+1。此时n-1个关键字相当于是划分出了n个数值范围,因此对应着n个指针,即 P 1 , P 2 , . . . . , P n P_1, P_2,....,P_n P1,P2,....,Pn,其中, P 1 P_1 P1指向关键字小于 K 1 K_1 K1的子节点, P 2 P_2 P2指向关键字属于 ( k 1 , k 2 ) (k_1, k_2) (k1,k2)的节点,以此类推。
  • 所有叶子节点位于同一层。

可以结合上面图来查看刚刚总结的这些特性。

相比平衡二叉树,B树的深度要更低,从而要进行的磁盘IO操作也更少,在数据查询中的效率就显得更高。

虽然M越大,一次读进内存的用来比较的数据就越多,但这个比较的过程是在内存里进行的,时间消耗可以忽略不计

什么是B+树

B+树是对B树的改进,主流的DBMS都支持B+树的索引方式,比如说MySQL。

B+树和B树的差异在哪儿呢?

  • 每个节点内的关键字数量和孩子数量一样。而B树中,孩子数量 = 关键字数量 + 1;
  • 非叶子节点的关键字也会同时出现在子节点里,并且是子节点关键字里的最大或者最小。而B树中,则不会同时出现在子节点中;
  • 非叶子节点仅用于索引,不保存数据记录,所有的数据记录都是放在叶子节点里。而B树中,所有的节点都是可以既保存索引,也保存数据记录。
  • 所有关键字都在叶子节点里出现,每个节点内部所有关键字按照大小从小到大顺序排列,所有叶子节点构成一个有序链表。

比如说下面这张图,就是一棵B+树:

在这里插入图片描述

比如说,想查找关键字16,就会自顶向下逐层进行查找,先后访问磁盘块1、磁盘块2、磁盘块7。三次IO操作即可。

在IO的次数上,B+ 树看起来似乎跟B树差不多,那么B+树到底好在哪儿呢?

这个要看B+树和B树的根本差异:B+树的中间节点并不直接存储数据

这样有什么好处呢?

首先,B+树查询效率更加稳定。B+树每次只有访问到叶子节点后才能取出数据,而B树中,由于非叶子节点也可以存储数据,这就造成了查询效率不稳定的情况,有时候需要访问到叶子节点才能找到数据,有时候走一半到非叶子节点就可以找到数据。时间不好量化。

其次,B+树查询效率更高。通常B+树比B树更矮胖(非叶子节点只存放索引,因此一个节点可以放更多关键字,从而减少深度),所需的磁盘IO就更少。同样的磁盘页大小,B+树可以存储更多的节点关键字。

在做区间查询的时候,B+树的效率同样比B树高。因为B+树里,所有的关键字都出现在叶子节点上,并通过有序链表进行了链接,非常适合寻找范围数据。而B树则需要通过中序遍历扫一遍才能完成范围数据的查找,效率要低很多。

总结

索引在使用时,时间的消耗主要是两部分带来的,一是读取磁盘块来取出里面保存的索引值数据,二是比较索引值数据。不过比较的工作是在内存中进行的,速度很快,所以这部分时间其实可以忽略不计。

因此,制约索引使用速度的唯一因素,就是与磁盘块的IO。只要能减少这块的IO,就能减少索引在使用时的时间消耗,从而提升整个查询的效率。

构造索引的时候,我们更倾向于采用矮胖的数据结构,因此平衡二叉树的结构被果断舍弃了。

B树和B+树都可以作为索引的数据结构,在MySQL中采用的是B+树,其查询性能更加稳定,在磁盘页大小相同的情况下,树的构造更加矮胖,所需要的IO次数更少,也更适合进行关键字的范围查找。

参考文献

  1. 24丨索引的原理:我们为什么用B+树来做索引?

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

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

相关文章

Vue3-18-侦听器watch()、watchEffect() 的基本使用

什么是侦听器 个人理解&#xff1a;当有一个响应式状态&#xff08;普通变量 or 一个响应式对象&#xff09;发生改变时&#xff0c;我们希望监听到这个改变&#xff0c;并且能够进行一些逻辑处理。那么侦听器就是来帮助我们实现这个功能的。侦听器 其实就是两个函数&#xff…

Process On在线绘制流程图

目录 一.ProcessOn 1.1.介绍 1.2.直接网上使用 二.绘制门诊流程图 三.绘制住院流程图 四.绘制药库采购入库流程图 五.绘制OA会议流程图 今天就到这里了哦!!!希望能帮到你哦&#xff01;&#xff01;&#xff01; 一.ProcessOn 1.1.介绍 ProcessOn&#xff08;流程&#…

智能优化算法应用:基于蝠鲼觅食算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蝠鲼觅食算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蝠鲼觅食算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝠鲼觅食算法4.实验参数设定5.算法结果6.…

Vue学习计划-Vue2--VueCLi(五)全局事件总线、消息订阅与发布(pubsub)

抛出问题:我们多级组件&#xff0c;或者任意不想关的子组件如何传递数据呢&#xff1f; 1. 全局事件总线&#xff08;$bus&#xff09; 一种组件间通信的方式&#xff0c;适用于任意组件间通信 全局事件总线示意图&#xff1a; 安装全局事件总线&#xff1a; new Vue({..…

无人机高空巡查+智能视频监控技术,打造森林防火智慧方案

随着冬季的到来&#xff0c;森林防火的警钟再次敲响&#xff0c;由于森林面积广袤&#xff0c;地形复杂&#xff0c;且人员稀少&#xff0c;一旦发生火灾&#xff0c;人员无法及时发现&#xff0c;稍有疏忽就会酿成不可挽救的大祸。无人机高空巡查智能视频监控是一种非常有效的…

MySQL如何进行Sql优化

&#xff08;1&#xff09;客户端发送一条查询语句到服务器&#xff1b; &#xff08;2&#xff09;服务器先查询缓存&#xff0c;如果命中缓存&#xff0c;则立即返回存储在缓存中的数据&#xff1b; &#xff08;3&#xff09;未命中缓存后&#xff0c;MySQL通过关键字将SQ…

19.(vue3.x+vite)v-if和v-for哪个优先级更高

前端技术社区总目录(订阅之前请先查看该博客) v-if和v-for哪个优先级更高 (1)实践中不应该把v-for和v-if放一起,可以包一层template (2)在vue2中,v-for的优先级是高于v-if (3)在vue3中,v-for的优先级是低于v-if 组件代码 <template><div><!--包一…

Hazel引擎学习(十二)

我自己维护引擎的github地址在这里&#xff0c;里面加了不少注释&#xff0c;有需要的可以看看 参考视频链接在这里 这是这个系列的最后一篇文章&#xff0c;Cherno也基本停止了Games Engine视频的更新&#xff0c;感觉也差不多了&#xff0c;后续可以基于此项目开发自己想要…

树莓派,opencv,Picamera2利用舵机云台追踪人脸

一、需要准备的硬件 Raspiberry 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目标…

数据结构与算法—排序算法(一)时间复杂度和空间复杂度介绍

排序算法 文章目录 排序算法1.排序算法的介绍1.1 排序的分类 2.算法的时间复杂度2.1 度量一个程序(算法)执行时间的两种方法2.2 时间频度2.2.1 忽略常数项2.2.2 忽略低次项2.2.3 忽略系数 2.3 时间复杂度2.3.1 常见的时间复杂度2.3.1.1 常数阶 O ( 1 ) O(1) O(1)2.3.1.2 对数阶…

Excel高效办公:文秘与行政办公的智能化革新

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f91f; 代理 IP 推荐&#xff1a;&#x1f449;品易 HTTP 代理 IP &#x1f485; 想寻找共同学习交流的小伙伴&#xff0c…

Java版本+鸿鹄企业电子招投标系统源代码+支持二开+Spring cloud +鸿鹄电子招投标系统

​项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。为了符合国家电子招投标法律法规及相关规范&#xff0…

java设计模式学习之【代理模式】

文章目录 引言代理模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用图片加载示例代码地址 引言 在现实生活中&#xff0c;我们经常使用代理来处理我们不想直接参与或无法直接参与的事务&#xff0c;例如&#xff0c;使用律师来代表法庭上的案件。在软件开发…

克隆图[中等]

一、题目 给你无向 连通 图中一个节点的引用&#xff0c;请你返回该图的 深拷贝&#xff08;克隆&#xff09;。图中的每个节点都包含它的值val&#xff08;int&#xff09;和其邻居的列表list[Node]。 class Node {public int val;public List<Node> neighbors; }测试…

计算机如何看待内存

计算机如何看待内存&#xff1b; 对象在内存中如何表示&#xff0c;如何操纵对象&#xff1b;

使用 Axios 进行网络请求的全面指南

使用 Axios 进行网络请求的全面指南 本文将向您介绍如何使用 Axios 进行网络请求。通过分步指南和示例代码&#xff0c;您将学习如何使用 Axios 库在前端应用程序中发送 GET、POST、PUT 和 DELETE 请求&#xff0c;并处理响应数据和错误。 准备工作 在开始之前&#xff0c;请…

Java 反射:探索运行时行为的强大工具

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、浅层理解 1.1 定义 1.2 我的理解 二、反射基础与应用 2.1 反射基础 2.2 反射的高级应用 三、一些反射的例子 3.1 获取类…

GitHub帐户管理更改电子邮件

登录到您的 GitHub 帐户&#xff1a; 前往 GitHub 网站并使用您的凭据登录。 访问个人设置&#xff1a; 单击右上角的您的头像&#xff0c;然后选择“Settings”&#xff08;设置&#xff09;。 选择电子邮件选项卡&#xff1a; 在左侧边栏中选择“Emails”&#xff08;电子邮…

快速入门Tailwind CSS:从零开始构建现代化界面

快速入门Tailwind CSS&#xff1a;从零开始构建现代化界面 介绍 Tailwind CSS 是一个以原子类的方式快速构建界面的 CSS 框架。它提供了丰富的预定义类&#xff0c;使得开发者能够快速构建样式和布局。 安装和设置 首先&#xff0c;我们需要在项目中安装 Tailwind CSS。可以…

CSS特效030:日蚀动画

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…