B+树索引及其原理

 MySQL索引的底层结构是B+树,为什么它会选择这个结构?联合索引是怎么实现的?最左侧匹配原则的原理是什么?本文将一一解答这些疑惑。

1 前置知识

在学习B+树之前,我们先了解下其他的树形结构:二叉树、平衡二叉树及B-树。将以循序渐进的方式来学习它们并比较它们的优缺点。

下面我们将在不同的树形结构上按顺序分别插入数字:5,9,6,33,14,7,8,10,22。

1.1 二叉树

性质:左子树的键值小于根的键值,右子树的键值大等于根的键值。

图 二叉树按照不同顺序插入数字后的形态

插入算法:自根向下插入,将会与根节点比较,如果大等于根节点则插入到右子树,否则插入到左子树。二叉树插入算法非常简单。

从上图,我们发现如果按照不同顺序插入数字,二叉树到形态会不一样的;同时,会发现上图右边两个二叉树的查询效率会比较低,因为它们“失衡”了,左子树和右子树高度不一致,将导致查询效率降低。

1.2 平衡二叉树

简称AVL Tree。自平衡二叉树。本质上还是一棵二叉树,其特点是:每个节点的左右子树高度差的绝对值(平衡因子)最多为1。

平衡二叉树的关键点是维持平衡。分为两步施行:

1)确定失衡姿态。先找到最小不平衡子树,从最小不平衡子树的根向插入节点数两步,即可确定。有四种失衡姿态:

LL

Left Left,左左。根节点的左子树的左子树的非空节点,导致根节点的左子树高度比右子树高2。

RR

Right Right,右右。插入或删除一个节点,根节点的右子树的右子树的非空节点,导致根节点的右子树的高度比左子树高2。

LR

Left Right,左右。根节点的左子树的右子树的非空节点,导致根节点的左子树的高度比右子树高2。

RL

Right Left,右左。根节点的右子树的左子树的非空节点,导致根节点的右子树的高度比左子树高2。

表 平衡二叉树失衡的四种姿态

图 平衡二叉树失衡的四种姿态

2)根据失衡姿态做相应调整来维持平衡。

LL

右单旋。

RR

左单旋。

LR

先左旋,使其成为LL姿态,然后再右旋。

RL

先右旋,使其成为RR姿态,然后再左旋。

表 平衡二叉树不同失衡姿态下的平衡策略

图 LR姿态调整到平衡状态的过程

缺陷:1)平衡二叉树在插入和删除过程中很容易失衡,因此需要频繁的重新保持平衡。2)当插入到平衡二叉树的数字极多时,二叉树将非常的高。而查询效率和树的高度成反比。

1.3 B-树

首先,这个读B树,不是读B减树。全名为平衡多路查找树。M阶B树表示其最多可以有M个子树(实际应用中,M的值非常大,这样的好处就是即使存储大量的数据,B树的高度仍然比较小)。

1.3.1 磁盘预读

数据库的数据是存储在磁盘上的,要提高查询效率,就需要减少系统与磁盘交互的次数。

系统从磁盘读取数据到内存时是以磁盘块为基本单位,位于同一磁盘块中的数据会被一起读取。InnoDB中的页是其磁盘管理的最小单位,默认大小是16KB(磁盘块往往没这么大)。InnoDB每次申请磁盘空间时都会是若干个连续地址的磁盘块来达到16KB(通常是整数倍)。

图 B树结构下的磁盘块逻辑图

在查询数据时,可以通过磁盘块中的信息连接到其他的磁盘块查找数据。当一个磁盘块下的子树越多,意味着系统访问的磁盘块数量越少。

1.3.2 B-树的性质

M阶B树有有以下性质:

1)根节点最少拥有两棵子树。

2)非根节点关键字个数n满足:ceil(m/2) -1<= n <= m-1; (ceil表示向上取整)。

3)有n棵子树的分支节点则一定存在n-1个关键字。关键字按照递增顺序进行排序。(n>0)

4)所有的叶子节点都在同一层。

B树的节点上存储了数值及指向子树的指针。

1.3.3 B树的插入与删除

B树在插入与删除过程中,需要保持一直它的性质。在这过程中破坏B树结构的主要因素是:节点的关键字数量不符合要求。

插入时先插入,后调整。

1

根据要插入的key值,找到叶子节点并插入。

2

判断当前节点的关键字个数是否满足要求,满足则操作结束,否则进行下一步。

3

以节点中间的key为中心分裂成左右两部分,然后将中间的key插入到父节点中,这个key的左子树指向分裂后的左部分,右子树指向分裂后的右部分。如果key所在的节点关键字不符合要求,则在这个节点上继续执行这一步。

表 B树的插入步骤

图 3阶级B树插入9

删除时分为两步:

1)查找并确定位置,并删除关键字,这一步有两种情况。

a)是叶子节点,则直接删除。

b)非叶子节点,需要用该关键字的后继关键字来填充该关键字,转化为在叶子节点删除一个关键字。后继关键字是其左子树最大的键值或右子树最小的键值。

2)调整B树以维持B树性质。

a)如果缺少节点的右邻兄弟存在且拥有多余的键,则左旋。

b)如果缺少节点的左邻兄弟存在且拥有多余的键,则右旋。

c)左右都没有多余的键,则将它与一个相邻兄弟节点以及父节点中它们的分隔值合并。如果B树失衡,则重新平衡父节点。

图 3阶B树删除14(删除阶段非叶子节点,9和22是后继节点)

图 3阶B树删除9(缺少节点的右邻兄弟存在多余键)

图 3阶B树删除14(合并节点后B树失衡)

1.3.4 B树的优缺点

优点:B树可以不要像平衡树那样频繁的重新保持平衡,同时树的高度远远低于平衡树,这样查询效率就能提高。

缺点:B树可能会没有完全填充,会浪费一些空间。B树也不适合范围查询(比如要查询6-12之间的值)。

2 B+树

对,这个读作B加树。M阶B+树有以下的性质:

1)根节点至少有一个关键字。

2)非根节点关键字数量n满足 ceil(m/2) <= n <= m。

3)有n个关键字必须有n个子女。

4)所有叶子节点在同一层,并且不包含任何信息(可看成是外部节点或查找失败的节点)。

5)关键字自小到大排列。

B+树的节点类型有两种,即内部节点(也叫索引节点)和叶子节点。内部节点不保存数据,只用于索引。

2.1 B+树的插入

插入操作全部在叶子节点上进行,且不能破坏关键字自小到大的顺序。B树的插入分四种情况:

1)被插入关键字所在节点,其关键字数目小于m,并且被插入值小等于该节点最大值,则直接插入。

2)被插入关键字所在节点,其关键字数目小于m,但是被插入值大于该节点最大值,则修正从根节点到当前节点到所有索引值,然后再进行插入。

3)被插入关键字所在节点,其关键字数目等于m,则将此节点分裂为左右两部分,中间的关键字放到父节点中。放入后如果父节点关键字数量小等于m,则操作完成,否则继续分离父节点。

图 3阶B+树插入55的过程

2.2 B+树的删除

B+树的删除与B树的删除算法有些类似。分为两种情况:

1)删除后节点关键字个数>=ceil(m/2)。

a) 如果被删除元素非索引值,则直接删除。

b)是索引值,则将该节点的索引值替换成被删除元素前一个元素,然后再删除。

2)删除后节点关键字个数<ceil(m/2)。

a)相邻兄弟节点有多余关键字,则删除后从其兄弟节点借一个关键字。

b)相邻兄弟节点没有多余关键字,则被删除其他痛其兄弟节点进行合并。(合并后如果破坏了B+树结构,则需要按B+树的性质进行修正。)

图 3阶B+树删除8的过程

2.3 B+树的优缺点

优点:与B 树一样不要频繁的维护其平衡,非常便于范围查找。

缺点:在插入及删除元素的过程中,所做的操作比较多。同时其叶子节点存储了相关的指针,也加大了整个的内存。

3 B+树索引

3.1 联合索引

mysql建立联合索引只会建立一棵B+树。与单值索引,其关键字多了几列(索引项)。排序时,先按照第一列排序,如果相等则按照下一列排序…依此类推。

3.2 MongoDB为什么使用B树作为底层结构

作为非关系型数据库,它对于遍历数据单需求没那么强,它追求的是查询单个记录的性能。

多数使用场景是读多写少。在MongoDB中单个数据查询需求比变量数据更常见。由于B树的非叶子节点也可以存储数据,所以查询一条数据所需的平均随机I/O次数也会比B+树少。这样查询速度也会更快。

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

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

相关文章

locust 快速入门--异常(Exceptions)与失败(Failures)

背景&#xff1a; 使用locust进行压测的时候&#xff0c;服务器响应已经异常了&#xff0c;但是从UI页面上看到的还是正常的响应。直至服务完全挂掉&#xff0c;才会出现异常信息。 locust认为HTTP响应代码是OK&#xff08;<400&#xff09;是成功的。实际服务的响应代码是2…

数据结构之堆——学习笔记

1.堆的简介&#xff1a; 接下来看一下堆的建立&#xff1b; 接下来是如何在堆中插入数据以及删除数据&#xff1a; 大根堆的插入操作类似只是改变了一下大于和小于符号&#xff0c;同时插入操作的时间复杂度为O&#xff08;logn&#xff09;。 来看几个问题&#xff1a; 答案当…

每日一题——LeetCode1051.高度检查器

方法一 sort排序&#xff1a; 创建一个元素和heights一模一样的expect数组 &#xff0c;将expect数组从小到大进行排序&#xff0c;比较heights和expect相同位置不同的元素个数 var heightChecker function(heights) {var expect [],count0for(const n of heights){expect.…

Ubuntu同步两个剪切板

众所周知&#xff0c;ubuntu系统中有两套剪切板。第一个剪切板是用鼠标操作&#xff0c;鼠标选中则复制&#xff0c;点击鼠标中键则粘贴&#xff08;这个剪切板通常叫做——选择缓冲区&#xff09;。第二个剪切板则是真正的剪切板&#xff0c;使用ctrlc&#xff08;在终端中默认…

qml的操作 -- VS2022开发qml,

在使用VS开发软件的时候一般大型软件都会使用模组的方式。每个模组之间独立开发&#xff0c;关于qml写的UI模组也不例外&#xff0c;如果所有的qml都挤在一个文件夹下也不利于管理&#xff0c;维护起来也比较吃力。比较好的管理方法就是按照功能分布存放在不同的文件夹下。还有…

网络实训模拟考察题目和答案(华为eNSP综合实验考试)

拓扑中四个交换机五个路由器&#xff0c;共九个设备 答案是对应的九个脚本&#xff08;从设备命名到保存&#xff09; 全部复制粘贴后&#xff0c;从PC1、PC2都是能Ping通服务器的&#xff08;保及格&#xff09;&#xff0c;其他要求没检查 题目 VLAN信息 设备名称端口链路…

windows 查看所有端口占用情况

winR&#xff0c;调出cmd窗口&#xff1a; 输入命令 netstat -ano 内容太多&#xff0c;显示不全&#xff0c;怎么办? 输入下面命令 netstat -ano > d:\1.log 在d盘根目录下就产生了 输出文件 打开可以看到如下内容 活动连接协议 本地地址 外部地址 状…

【Android取证篇】小米手机OTG取证知识

【Android取证篇】小米手机OTG取证知识 小米手机OTG使用方法—【蘇小沐】 目录 1、OTG用途 2、手机连不上U盘 3、小米手机有没有OTG 4、手机usb调试找不到 5、MHL能否在HDMI输出视频的同时进行USB传输 1、OTG用途 使用OTG外接设备&#xff0c;需要使用和手机接口对应匹配的…

JSP+Servlet 重要知识点 (含面试题)

JSP是Servlet技术的扩展&#xff0c;本质上就是Servlet的简易方式。JSP编译后是“类servlet”。 这里提一句&#xff1a; jsp已经没有深入学习的必要了&#xff0c;除了维护老项目能用上一些&#xff0c;基本属于被淘汰的边缘了。Servlet还是有必要学习一下&#xff0c;比如sp…

【本科生通信原理】【实验报告】【北京航空航天大学】实验四:模拟信号的数字化及编码

目录 一、实验目的二、实验内容三、实验程序四、实验结果五、实验分析六、参考文献 一、实验目的 1、掌握低通信号的抽样及重建过程&#xff1b; 2、掌握PCM的编码及译码过程。 二、实验内容 共2问&#xff1a; 三、实验程序 1、 function q1() dt 0.001; % 时间分辨率…

如何本地搭建DolphinScheduler并无公网ip远程访问管理界面

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

通过cpolar在公网访问本地网站

通过cpolar可以轻松将本地网址映射到公网进行访问&#xff0c;下面简要介绍一下实现步骤。 目录 一、cpolar下载 二、安装 三、使用 3.1 登录 3.2 创建隧道 一、cpolar下载 cpolar官网地址&#xff1a;cpolar - secure introspectable tunnels to localhost 通过QQ邮箱…

网络请求 - 异步编程详解

一、概述 网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1a;通过HTTP发起一个数据请求。WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接。Socket连接&#xff1a;通过Socket进行数据传输。 HTTP和WebSocket都是啥&#xff1f; 比如我…

MyBatis - 批量更新(update foreach)报错

在使用mybatis执行批量更新(update foreach)数据的时候报错如下&#xff1a; org.springframework.jdbc.BadSqlGrammarException: ### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; c…

基于web3+solidity的众筹项目

基本配置&#xff1a;node、npm、yarn&#xff0c;安装ganache&#xff0c;chrome&#xff0c;chrome安装插件MetaMask&#xff0c; 主要功能&#xff1a;目的是实现一个简单的众筹平台&#xff0c;允许用户发起筹款项目、捐款、提出使用资金请求以及证明人证明。 部分合约&…

echarts 仪表盘进度条 相关配置

option {series: [{type: gauge,min: 0,//最大值max: 100, //最小值startAngle: 200,//仪表盘起始角度。圆心 正右手侧为0度&#xff0c;正上方为90度&#xff0c;正左手侧为180度。endAngle: -20,//仪表盘结束角度splitNumber: 100, //仪表盘刻度的分割段数itemStyle: {color…

深度学习|4.1 深L层神经网络 4.2 深层网络的正向传播

4.1 深L层神经网络 对于某些问题来说&#xff0c;深层神经网络相对于浅层神经网络解决该问题的效果会较好。所以问题就变成了神经网络层数的设置。 其中 n [ i ] n^{[i]} n[i]表示第i层神经节点的个数&#xff0c; w [ l ] w^{[l]} w[l]代表计算第l层所采用的权重系数&#xff…

day07 四数相加Ⅱ 赎金信 三数之和 四数之和

题目1&#xff1a;454 四数相加Ⅱ 题目链接&#xff1a;454 四数相加Ⅱ 题意 4个整数数组nums1&#xff0c; nums2&#xff0c; nums3&#xff0c; nums4的长度均为n&#xff0c;有多少个元组&#xff08;i&#xff0c;j&#xff0c;k&#xff0c;l&#xff09;使得 nums[…

Python如何生成个性二维码

Python-生成个性二维码 一、问题描述 通过调用MyQR模块来实现生成个人所需二维码。 安装&#xff1a; pip install myqr 二、代码实现 1.普通二维码 from MyQR import myqr # 普通二维码 myqr.run(wordshttp://www.csdn.net/mayi0312,save_nameqrcode.png ) 效果图&#…

@JsonFormat与@DateTimeFormat

JsonFormat注解很好的解决了后端传给前端的格式&#xff0c;我们通过使用 JsonFormat可以很好的解决&#xff1a;后台到前台时间格式保持一致的问题 其次&#xff0c;另一个问题是&#xff0c;我们在使用WEB服务的时&#xff0c;可 能会需要用到&#xff0c;传入时间给后台&am…