B+树的介绍

B+树的概念
规则:

B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加
B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样
B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针
非叶子节点的子节点数=关键字数(来源百度百科)(Mysql 的B+树)

B+树相比于B树的优点

由于B+树在内部节点上不好含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的数据也具有更好的缓存命中率;
B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。
总结:B+树的I/O次数更少,磁盘读写代价更低,时间更稳定,范围搜索更好

B+树的存在形式

  1. 结点内有n个元素就会n个子结点;每个元素是子结点元素里的最大值或最小值。
  2. 结点内有n个元素就会n+1个子结点;最左边的子结点小于最小的元素,其余的子结点是>=当前元素。

B+树实现
以第一种形式实现

B+树节点参数
protected  int degree;//阶数
    protected  BPlusNode<K,V> parent;//父节点
    protected  int keyNum;//关键字个数
    protected  LinkedList<K> keys;//存放数据项的list,K为key
    protected  boolean isLeaf;//是否为叶子节点

    LinkedList<BPlusNode<K,V>> childList;//存放孩子节点list

    public  BPlusNode(int degree){
        if (degree<3) throw new IllegalArgumentException("The BPlusTree degree must be at least three!");
        this.degree = degree;
        parent=null;
        keys= new LinkedList<>();
        childList= new LinkedList<>();
    }

    //查找
    abstract BPlusNode<K,V> search(K key);

    //删除
    abstract BPlusNode<K,V> delete(K key);
    //插入
    abstract BPlusNode<K,V> insert(K key,V value);

    //上溢
    protected  boolean isOverFlow(){
        return  keyNum >degree;
    }
    //下溢
    protected  boolean isUnderFlow(){

        return  keyNum<Math.ceil(degree/2.0);
    }

```java
    public V  searchData(K key){
        Objects.requireNonNull(key);
        var search =(LeafNode<K, V>) root.search(key);
        if (search.insertIndex<search.entryKey.size()){

            var  searchEntry = search.entryKey.get(search.insertIndex);
            if (searchEntry.key().equals(key)) return searchEntry.value();
        }

        return null;
    }

操作原理

  • 查找操作:从根节点开始,将待查找的关键字与当前节点的关键字进行比较。如果待查找的关键字小于当前节点的最小关键字,则沿着最左边的指针进入下一层节点继续查找;如果待查找的关键字大于当前节点的某个关键字,则沿着相应的指针进入下一层节点。重复这个过程,直到找到目标关键字所在的叶子节点。由于叶子节点之间是有序链表,因此在找到叶子节点后,可以方便地在链表中进行顺序查找,以找到所有匹配的记录。
  • 插入操作:首先进行查找操作,找到合适的叶子节点位置。如果叶子节点未满,则直接将新的关键字插入到叶子节点中,并保持叶子节点的有序性;如果叶子节点已满,则需要对叶子节点进行分裂操作。将叶子节点平均分成两部分,将中间关键字上移到父节点中,并在父节点中插入一个指向新分裂出的叶子节点的指针。如果父节点也已满,则需要对父节点进行类似的分裂操作,直到找到一个未满的父节点或者到达根节点。如果根节点已满,则创建一个新的根节点,将原来的根节点分裂为两个子节点,并将中间关键字插入到新根节点中。
  • 删除操作:先通过查找操作找到要删除的关键字所在的叶子节点。如果该关键字所在的叶子节点中的关键字数量大于最小值(通常为分支因子的一半向上取整),则直接删除该关键字,并保持叶子节点的有序性;如果该叶子节点中的关键字数量等于最小值,且其左右兄弟节点中有一个节点的关键字数量大于最小值,则可以从兄弟节点中借一个关键字过来,或者将兄弟节点与该叶子节点合并。如果兄弟节点的关键字数量也都等于最小值,则需要将该叶子节点与一个兄弟节点合并,并将父节点中对应的关键字删除。如果父节点中的关键字数量小于最小值,则需要对父节点进行类似的调整操作,直到满足 B + 树的结构要求。

优势

  • 高效的查找性能:由于 B + 树的高度相对较低,且叶子节点形成有序链表,因此无论是随机查找还是范围查找,都能够在较短的时间内完成。
  • 支持顺序访问:叶子节点之间的链表结构使得可以方便地进行顺序访问,这对于需要按照顺序处理数据的应用场景非常有利,如范围查询、排序等。
  • 磁盘 I/O 优化:B + 树的节点通常较大,可以容纳多个关键字和指针,使得一次磁盘 I/O 能够读取更多的数据,从而减少磁盘 I/O 的次数,提高系统的整体性能。

应用场景

  • 数据库管理系统:用于存储和索引数据库中的表数据,如 MySQL、Oracle 等数据库都广泛使用 B + 树来实现索引结构,以提高数据的查询效率。
  • 文件系统:在文件系统中,B + 树可以用于存储文件目录信息,快速定位文件的存储位置,提高文件系统的性能。

MySQL中的B+树是怎么实现的:

MySQL 中的 B + 树主要是通过以下方式实现的:

数据结构定义

  • 节点结构:B + 树的节点通常包含多个关键字和对应的数据指针。非叶子节点只存储关键字和指向下一层节点的指针,而叶子节点除了关键字外,还存储了实际的数据记录或者指向数据记录的指针。
  • 关键字有序排列:节点中的关键字按照从小到大的顺序排列。这使得在查找、插入和删除操作时能够快速定位到目标关键字的位置。

查找操作实现

  • 从根节点开始,将待查找的关键字与节点中的关键字进行比较。
  • 如果待查找关键字等于当前节点的某个关键字,则根据该关键字对应的指针找到相应的数据记录。
  • 如果待查找关键字小于当前节点的最小关键字,则沿着最左边的指针继续查找下一层节点。
  • 如果待查找关键字大于当前节点的最大关键字,则沿着最右边的指针继续查找下一层节点。
  • 如果待查找关键字介于当前节点的两个关键字之间,则根据节点中关键字的排列顺序,找到对应的指针,继续查找下一层节点,直到找到目标关键字或到达叶子节点确定不存在该关键字为止。

插入操作实现

  • 首先进行查找操作,找到合适的叶子节点来插入新的关键字。
  • 如果叶子节点未满,则直接将新关键字插入到合适的位置,保持关键字的有序性。
  • 如果叶子节点已满,则需要对该叶子节点进行分裂操作。将叶子节点中的关键字和数据指针平均分成两部分,将中间关键字提升到父节点中,并将新的关键字插入到合适的子节点中。如果父节点也已满,则需要递归地对父节点进行分裂操作,直到找到一个未满的父节点或者到达根节点。如果根节点也已满,则创建一个新的根节点,将原来的根节点分裂成两个子节点,并将中间关键字提升到新的根节点中。

删除操作实现

  • 先通过查找操作找到包含要删除关键字的叶子节点。
  • 如果要删除的关键字所在的叶子节点中的关键字数量大于最小关键字数量限制,则直接从该叶子节点中删除关键字,并调整关键字的顺序以保持有序性。
  • 如果删除关键字后,叶子节点中的关键字数量小于最小关键字数量限制,则需要进行调整操作。可以从相邻的兄弟节点中借调关键字,或者与兄弟节点进行合并操作。如果相邻兄弟节点中的关键字数量足够,则可以将兄弟节点中的一个关键字移动到当前节点中,以保持节点的关键字数量平衡。如果相邻兄弟节点中的关键字数量也不足,则需要将当前节点和兄弟节点合并成一个新的节点,并将父节点中对应的关键字和指针进行相应的调整。如果父节点中的关键字数量小于最小关键字数量限制,可能需要递归地对父节点进行调整操作,直到满足 B + 树的平衡条件为止。

索引组织方式

  • 在 MySQL 中,B + 树索引是基于表中的列来创建的。对于不同的数据类型和索引类型,B + 树的实现细节会有所不同。例如,对于整数类型的索引列,关键字的比较和排序操作相对简单直接;而对于字符串类型的索引列,通常需要根据字符集和排序规则来进行比较和排序。
  • 聚簇索引和非聚簇索引在 B + 树的实现上也有一些差异。聚簇索引的叶子节点直接存储了数据记录,而非聚簇索引的叶子节点存储的是指向数据记录的指针。因此,在使用聚簇索引进行查找时,可以直接获取到数据记录,而使用非聚簇索引查找时,还需要根据指针再去查找相应的数据记录。

MySQL中索引实现原理:

MySQL 中的索引是一种用于提高查询效率的数据结构,其实现原理主要基于 B + 树等数据结构,以下是详细介绍:

B + 树数据结构基础

  • 节点结构:B + 树的节点包含多个关键字和对应的数据指针。非叶子节点仅存储关键字与指向下一层节点的指针,用于引导搜索路径;叶子节点除关键字外,还存储实际的数据记录或指向数据记录的指针。
  • 关键字有序排列:节点内的关键字按从小到大的顺序排列,便于快速查找、插入和删除操作时定位目标关键字。

索引的组织方式

  • 聚簇索引:基于表中某一列或多列组合构建。叶子节点直接存储数据记录,数据在物理存储上按聚簇索引列的值顺序排列。一个表只能有一个聚簇索引,通常主键会被自动设为聚簇索引。如CREATE TABLE语句中使用PRIMARY KEY定义主键时,MySQL 会自动创建聚簇索引。
  • 非聚簇索引:叶子节点存储的是指向数据记录的指针,而非数据记录本身。一个表可以有多个非聚簇索引,可基于表中的其他列创建,用于加速对该列的查询。通过CREATE INDEX语句创建非聚簇索引,如CREATE INDEX index_name ON table_name (column_name);

索引的查找过程

  • 从根节点开始,将查询条件中的关键字与节点中的关键字比较。若相等,则根据指针找到对应数据记录;若小于最小关键字,沿最左边指针找下一层节点;若大于最大关键字,沿最右边指针找下一层节点;若介于两个关键字之间,按顺序找到对应指针继续查找,直至找到目标关键字或确定不存在。

索引的插入与维护

  • 插入操作:先查找合适的叶子节点插入新关键字。若叶子节点未满,直接插入并保持有序;若已满,则分裂节点,将关键字和指针平均分成两部分,中间关键字提升到父节点,新关键字插入合适子节点,若父节点也满,则递归分裂,直至找到未满父节点或到达根节点,根节点满则创建新根节点。
  • 删除操作:先找到包含要删除关键字的叶子节点,若删除后关键字数量大于最小限制,直接删除并调整顺序;若小于最小限制,则需调整,可从相邻兄弟节点借调关键字或合并节点,若兄弟节点关键字数量够,可移动一个关键字到当前节点,若都不足,则合并节点,并调整父节点关键字和指针,若父节点关键字数量不足,需递归调整,直至满足 B + 树平衡条件。

不同数据类型的索引实现特点

  • 整数类型:比较和排序操作简单直接,索引查找效率高。
  • 字符串类型:需根据字符集和排序规则比较排序,字符集不同排序结果和索引结构可能不同,如 UTF-8 和 GBK 字符集对汉字的编码和排序方式有差异。

索引的优缺点及使用注意事项

  • 优点:大大提高查询速度,尤其对大数据量表和复杂查询条件,能快速定位数据,减少磁盘 I/O 操作,提升数据库性能。
  • 缺点:占用额外存储空间,索引需存储关键字和指针等信息;插入、更新和删除操作时,需维护索引结构,增加数据操作时间成本。
  • 注意事项:并非列都适合建索引,如数据重复度高的列建索引效果差;索引列应选常用于查询条件、连接条件和排序条件的列;定期分析查询语句执行计划,根据实际情况调整索引,以保证索引的有效性。

 

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

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

相关文章

面试经典 150 题:20、2、228

20. 有效的括号 参考代码 #include <stack>class Solution { public:bool isValid(string s) {if(s.size() < 2){ //特判&#xff1a;空字符串和一个字符的情况return false;}bool flag true;stack<char> st; //栈for(int i0; i<s.size(); i){if(s[i] ( |…

NFS-Ganesha 核心架构解读

NFSv4 简要概述 NFS 这个协议( NFSv2 )最初由 Sun Microsystems 在 1984 年设计提出&#xff0c;由于存在一些不足&#xff0c;因此在随后由几家公司联合推出了 NFSv3。到了 NFSv4 时&#xff0c;开发完全由 IETF 主导&#xff0c;设计目标是&#xff1a; 提高互联下的 NFS 访…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

mysql数据库(五)多表查询

多表查询 文章目录 多表查询一、链表查询1.1交叉连接1.2 内连接1.3 左连接1.4 右连接1.5 全连接1.6 例子 二、子查询2.1 in与not in2.2 any/some2.3 all2.4 比较运算符2.5 exists 三、例子 查询中使用的表如下所示 ------------ | id | name | ------------ | 1 | IT | …

Redis设计与实现 学习笔记 第十七章 集群

Redis集群是Redis提供的分布式数据库方案&#xff0c;集群通过分片&#xff08;sharding&#xff0c;水平切分&#xff09;来进行数据共享&#xff0c;并提供复制和故障转移功能。 17.1 节点 一个Redis集群通常由多个节点&#xff08;node&#xff09;组成&#xff0c;在刚开…

分布式----Ceph部署

目录 一、存储基础 1.1 单机存储设备 1.2 单机存储的问题 1.3 商业存储解决方案 1.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 1.5 分布式存储的类型 二、Ceph 简介 三、Ceph 优势 四、Ceph 架构 五、Ceph 核心组件 #Pool中数据保存方式支持两种类型&…

【Qt聊天室客户端】消息功能--发布程序

1. 获取文件内容 主要目标是实现获取内容二进制数据的接口&#xff0c;主要是为后面的消息功能提供服务 具体实现 客户端发送请求 服务端处理请求&#xff0c;同时支持三种数据类型 客户端处理服务端的响应 2. 发送图片消息 客户端与服务端的通信约定 客户端从服务器中获取图片…

ab (Apache Bench)的使用

Apache Bench&#xff08;ab&#xff09;是一个用于基准测试HTTP Web服务器的命令行工具&#xff0c;广泛用于评估和优化Web服务器的性能。以下是关于Apache Bench的详细介绍&#xff0c;包括其功能、使用方法、常用参数和输出结果解析。 功能 性能测试&#xff1a;通过模拟多…

【HarmonyNext】显示提示文字的方法

【HarmonyNext】显示提示文字的方法 本文介绍在 HarmonyNext 中显示提示文字的两种常见方法&#xff1a;使用自定义弹窗 CustomDialog 和使用 promptAction 的 showToast 方法。 一、使用自定义弹窗 CustomDialog 在 HarmonyNext 中&#xff0c;自定义弹窗是实现复杂提示信…

第三十一天|贪心算法| 56. 合并区间,738.单调递增的数字 , 968.监控二叉树

目录 56. 合并区间 方法1&#xff1a;fff 看方法2&#xff1a;fff优化版 方法3&#xff1a; 738.单调递增的数字 968.监控二叉树&#xff08;贪心二叉树&#xff09; 56. 合并区间 判断重叠区间问题&#xff0c;与452和435是一个套路 方法1&#xff1a;fff 看方法2&am…

【自用】0-1背包问题与完全背包问题的Java实现

引言 背包问题是计算机科学领域的一个经典优化问题&#xff0c;分为多种类型&#xff0c;其中最常见的是0-1背包问题和完全背包问题。这两种问题的核心在于如何在有限的空间内最大化收益&#xff0c;但它们之间存在一些关键的区别&#xff1a;0-1背包问题允许每个物品只能选择…

【Unity】ScriptableObject的应用:利用配方合成新物体

前一篇已经使用ScriptableObject(SO)类配置可放置物体&#xff0c;本篇探索更多的SO类应用场景。 需求分析 将若干指定物体放在工作台上&#xff0c;可以生成新的物体。 成果展示 Scene部分 准备工作台&#xff0c;放在工作台上的物体全部放在指定PlacedObjects空物体下。 …

STM32设计学生宿舍监测控制系统

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 随着科技的飞速发展和智能化时代的到来&#xff0c;学生宿舍的安全、舒适…

TofuAI处理BT1120时序视频要求

时序要求 BT.1120视频用于1920x108030Hz数字视频输入。具体时序必须严格按照说明。BT.1120输入电平为1.8V。 BT1120数字视频采用YCbCr彩色格式输出&#xff0c;串行数据位宽为16bit&#xff0c;亮度在 高8bit&#xff0c;色度在低8bit&#xff0c;亮度和色度在同一个时钟周期输…

C++内存池实现

1.内存池概念 内存池就和其他的池数据&#xff08;如线程池&#xff09;结构类似&#xff0c;由程序维护一个“池”结构来管理程序使用的内存&#xff0c;然后根据需要从内存池中申请使用内存或者向内存池中释放内存&#xff0c;来达到高效管理内存的目的。 在一般的内存管理的…

设计模式-参考的雷丰阳老师直播课

一般开发中使用的模式为模版模式策略模式组合&#xff0c;模版用来定义骨架&#xff0c;策略用来实现细节。 模版模式 策略模式 与模版模式特别像&#xff0c;模版模式会定义好步骤定义好框架&#xff0c;策略模式定义小细节 入口类 使用模版模式策略模式开发支付 以上使用…

Vue3打包自动生成版本JSON文件,添加系统版本检查,实现系统自动更新提示

实现该功能一共有三步。废话不多说&#xff0c;直接上代码&#xff01;&#xff01;&#xff01; 第一步&#xff1a;打包时自动生成版本信息的js文件&#xff0c;versionUpdate.js import fs from fs; import path from path; import { ElMessageBox } from element-plus; i…

华为云前台展示公网访问需要购买EIP,EIP流量走向

华为云前台网络&#xff08;VPC,安全组&#xff0c;EIP&#xff09; 1.EIP网段是从哪里划分的&#xff1f; 管理员在后台Service_OM已设置 Service_OM-网络资源-外部网络-创建外部网络基本信息&#xff1a;配置参数&#xff1a;*名称 public*网络类型 LOCAL 不带标签 类似开…

[Mysql基础] 表的操作

一、创建表 1.1 语法 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 说明&#xff1a; field 表示列名 datatype 表示列的类型 character set 字符集&#xff0c;如果没有指定字符集…

ASP.NET MVC宠物商城系统

该系统采用B/S架构&#xff0c;使用C#编程语言进行开发&#xff0c;以ASP.NET MVC框架为基础&#xff0c;以Visual Studio 2019为开发工具&#xff0c;数据库采用SQL Server进行保存数据。系统主要功能包括登录注册、宠物展示、个人中心、我的订单、购物车、用户管理、宠物类别…