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.mfbz.cn/a/297077.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

互联网加竞赛 基于人工智能的图像分类算法研究与实现 - 深度学习卷积神经网络图像分类

文章目录 0 简介1 常用的分类网络介绍1.1 CNN1.2 VGG1.3 GoogleNet 2 图像分类部分代码实现2.1 环境依赖2.2 需要导入的包2.3 参数设置(路径&#xff0c;图像尺寸&#xff0c;数据集分割比例)2.4 从preprocessedFolder读取图片并返回numpy格式(便于在神经网络中训练)2.5 数据预…

Plantuml之nwdiag网络图语法介绍(二十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

HTTP协议-Cookie和Session详解

1|0前置&#xff1a; 会话&#xff08;Session&#xff09;跟踪是Web程序中常用的技术&#xff0c;用来跟踪用户的整个会话。常用的跟踪技术就是Cookie和Session。 Cookie通过在客户端记录信息确定用户身份&#xff0c;Session通过在服务器记录确定用户身份。 本章将系统的讲…

我的第一个前端项目,vue项目从零开始创建和运行

​入门前端&#xff0c;从基础做起&#xff0c;从零开始新建项目 背景&#xff1a;VUE脚手架项目是一个“单页面”应用&#xff0c;即整个项目中只有1个网页&#xff01; 在VUE脚手架项目中&#xff0c;主要是设计各个“视图组件”&#xff0c;它们都是整个网页中某个部分&…

养乐多公司确认 95 G 用户私密数据被泄露

一名自称为DragonForce的组织声称已经公开泄露了澳大利亚养乐多公司&#xff08;Yakult Australia&#xff09;的95.19 GB数据。Yakult Australia证实了这次网络攻击的真实性&#xff0c;并表示公司在澳大利亚和新西兰的IT系统都受到了影响。 该公司在一份声明中表示&#xff…

(2024,少样本微调自适应,泛化误差界限,减小泛化误差的措施)多模态基础模型的少样本自适应:综述

Few-shot Adaptation of Multi-modal Foundation Models: A Survey 公和众和号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 多模态基础模型的预训练 3. 多模态基础模…

第九节HarmonyOS 常用基础组件8-Span

1、描述 作为Text组件和RichEditor组件的子组件&#xff0c;用于显示行内文本的组件。 2、接口 Span(value:string | Resource) 3、参数 value - string | Resource - 必填 - 文本内容。 4、属性 名称 参数类型 描述 decoration { type: ;TextDecorationType, color?…

用单片机设计PLC电路图

自记&#xff1a; 以下为PMOS推挽输出及集成块光耦&#xff1a;

算法日志的存在核心在于搭建自检系统

"相信每一个人执行与日志有关的任务都会遇到这样难题吧&#xff1f;长达几万行的日志&#xff0c;如果我们单纯用肉眼去一个个排查&#xff0c;那么恐怕所耗费的时间是以天为计量单位了。当然这是一种比较夸张的情况&#xff0c;根据我的项目经验&#xff0c;正常情况是十…

基于FFmpeg的短视频编辑工具Cut

前言 最近在学习FFmpeg和音视频的相关知识&#xff0c;为了加强对FFmpeg的认识和了解&#xff0c;于是撸了一个短视频编辑软件Cut。 效果图先行&#xff1a; 技术点 启动页优化 但启动app的时候会有一个短暂的黑屏或者白屏。为什么呢&#xff1f; 是因为在App启动时&#x…

腾讯云2核2G3M服务器够用吗?腾讯云2核2G3M云服务器性能评测

阿里云轻量应用服务器2核2G3M带宽优惠价格62元一年&#xff0c;100%CPU性能&#xff0c;3M带宽下载速度384KB/秒&#xff0c;40GB SSD系统盘&#xff0c;月流量200GB&#xff0c;折合每天6.6GB流量&#xff0c;超出月流量包的流量按照0.8元每GB的价格支付流量费&#xff0c;地域…

kubesphere和k8s的使用分享

文章目录 什么是kubernetesKubernetes的部分核心概念互式可视化管理平台与kubernetes的关系市面是常见的kubernetes管理平台 什么是kubesphereKubesphere默认安装的组件Kubesphere涉及的服务组件kubesphere的安装Kubesphere相关的内容 什么是kubernetes 就在这场因“容器”而起…

Vue CLI组件通信

目录 一、组件通信简介1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 二、props1.Props 定义2.Props 作用3.特点4.代码演示 三、props校验1.思考2.作用3.语法4.代码演示 四、prop…

科锐16位汇编学习笔记 03 汇编指令

指令种类 数据传送指令算数运算类指令位操作类指令串操作类指令控制转移类指令处理器控制类指令 数据传送类指令 传送类指令不影响标志位&#xff0c;**除了标志位传送指令外。** 传送指令MOV&#xff08;move&#xff09; 说明 ​ 把一个字节或字的操作数从源地址传送至…

swift ——多行文字前面内容省略

首先来说一说ios中的 lineBreakModelineBreakMode : 设置文字过长时的显示截断样式 可选值如下 byWordWrapping &#xff1a; 以单词为单位换行&#xff0c;以单词为单位截断。byCharWrapping &#xff1a;以字符为单位换行&#xff0c;以字符为单位截断。byClipping &#x…

Linux进程管理、ps命令、kill命令

每一个程序在运行的时候都会被操作系统注册为系统中的一个进程 补充一下操作系统的内容&#xff1a; 进程实体&#xff08;又称进程映像&#xff09;&#xff1a;程序段、相关数据段、PCB三部分构成 进程是进程实体的运行过程&#xff0c;是系统进行资源分配的一个独立单位 …

关于时间格式yyyy-M-d或yyyy-MM-d到yyyy-MM-dd的转换

工作时遇到前端传的时间格式是"2023-12-3 17:41:52"&#xff0c;和"2023-1-1 17:41:52"但是我想要的是"2023-12-03 17:41:52"和"2023-01-01 17:41:52"。下面给大家分享几个解决方法 方法一&#xff1a; 找前端&#xff01;让他改&…

关于《码农翻身》一书的读后感以及自己的一些拙见汇总

书籍名称 《码农翻身》 | 刘欣&#xff08;码农翻身&#xff09; 著 | 文章将以问答的形式进行叙述 1.是从什么渠道接触到《码农翻身》的 一个工作日的下午&#xff0c;手上的任务基本结束&#xff0c;翻了翻桌上的书和笔记之类的&#xff0c;同事见我在看书&#xff0c;于是向…

用opencv的DNN模块做Yolov5目标检测(纯干货,源码已上传Github)

最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章&#xff0c;但是没看到过用opencv的dnn模块做yolov5目标检测的。于是&#xff0c;我就想着编写一套用opencv的dnn模块做yolov5目标检测的程序。在编写这套程序时&#xff0c;遇到的bug和解决办法&#xff0c…

Mac启动时候出现禁止符号

Mac启动时候出现禁止符号 启动时候出现禁止符号,意味着 选定的启动磁盘 包含 Mac 操作系统&#xff0c;但它不是 您的 Mac 可以使用的 macOS 。您应该在这个磁盘上 重新安装 macOS 。 可以尝试以下苹果提供的方法&#xff1a; Mac启动时候出现禁止符号 不要轻易抹除磁盘&am…