从 Hash索引、二叉树、B-Tree 与 B+Tree 对比看索引结构选择

news2024/11/19 4:38:17

从 Hash索引、二叉树、B-Tree 与 B+Tree 对比看索引结构选择

  • 1、Hash 结构
    • 1.1、关于 Hash 数据结构
    • 1.2、InnoDB索引为啥不选 Hash 结构
    • 1.3、关于InnoDB 提供自适应 Hash 索引 (Adaptive Hash Index)
  • 2、二叉搜索树
  • 3、平衡二叉树(AVL树 )
  • 4、B-Tree(B树)
  • 5、B+Tree (B+树)
    • 5.1、B+Tree 结构
    • 5.2、B+Tree 相关思考题

       数据结构可以说是程序员常用,但大部分人不知其所以然的知识点,本文将对Hash、二叉搜索树、平衡二叉树、B-Tree、B+Tree几种数据做一下梳理和总结。
 

1、Hash 结构

 

1.1、关于 Hash 数据结构

 
Hash 本身是一个函数,又被称为散列函数,可以大幅提升检索数据的效率。

  • Hash 算法是通过某种特定性的算法(比如:MD5、SHA1、SHA2、SHA3)将输入转变为输出。相同的输入永远可以得到相同的输出,假设输入内容有微小偏差,在输出中通常会有不同的结果。

  • Hash值的长度是固定的,而输入数据的可能性是无限的,这就会出现不同的输入数据映射到了相同的Hash值,这种现象就叫Hash碰撞

  • 解决Hash碰撞的常见方案有开放寻址法和链表法。开放寻址法是在发生碰撞时,尝试寻找下一个可用的槽位来存储数据。链表法则是将映射到同一个Hash值的数据存储在一个链表中,通过链表来解决碰撞问题

  • 当链表长度过长时,查询效率会降低,此时可以将链表转换为红黑树来提高查询效率。红黑树是一种自平衡的二叉查找树,能够保证最坏情况下的查询时间复杂度为O(log n),其中n为节点数量。

在这里插入图片描述
举例:如果想要验证两个文件是否相同,可以直接对比两个文件通过Hash函数计算出的结果,如两个文件通过Hash函数计算的结果一样,即文件相同,否则不同。

 
提高查询速度的数据结构,常见的有两类:

  • 树,例如:平衡二叉树,查询、插入、修改、删除的平均时间复杂度都是O(log2N) .
  • 哈希,例如:HashMap,查询、插入、修改、删除的平均时间复杂度都是O(1) ;(key,value)

采用 Hash 进行检索效率非常高,基本都是一次检索就能找到数据,B+Tree 需要自顶向下依次查找,多次访问节点才能找到数据,中间需要多次 I/O 操作,从效率上来将 Hash 比 B+Tree 更快

Hash 索引适用的存储引擎如表所示:

索引/存储引擎InnoDBMyISAMMemory
Hash 索引不支持不支持支持

Hash 索引的使用场景:

  • ① 当字段的重复度低,且经常需要进行等值查询时,采用 Hash 索引是个不错的选择。

  • ② Redis 存储的核心就是 Hash 表。

  • ③ InnoDB 提供自适应 Hash 索引 (Adaptive Hash Index)
     

1.2、InnoDB索引为啥不选 Hash 结构

 
Hash结构效率高,那为啥InnoDB的索引结构要设计成树型呢?

  • 原因①,Hash索引仅能满足 (=)(<>)和 in 查询。如果进行 范围查询,时间复杂度会退化为O(n),树型结构的有序特性,依然能保持 O(log2N) 的高效率。
  • 原因②,Hash索引有一个缺陷,数据的存储是没有顺序的,在 ORDER BY 的情况下,使用 Hash 索引还需要对数据重新排序。
  • 原因③,对于联合索引而言,Hash值是将联合索引键合并后一起来计算,无法对单独的一个键或几个索引键进行查询。
  • 原因④,对于等值查询而言,通常 Hash 索引的效率更高,但如果索引列的重复值很多,效率就会降低。因为当遇到 Hash 冲突时,需要遍历桶中的行指针来进行比较,找到查询的关键字,非常耗时。故 Hash 索引常不会用到重复值多的列上,比如 性别、年龄等。

 

1.3、关于InnoDB 提供自适应 Hash 索引 (Adaptive Hash Index)

 
       如果某个数据经常被访问,当满足一定条件时,会将这个数据页的地址存放到 Hash 表中,下次查询的时候,就会直接找到这个数据页所在的位置。采用自适应 Hash 索引的目的就是,方便根据 SQL 的查询条件,加速定位到叶子节点,特别是当 B+Tree 比较深,层级比较多时,自适应Hash能显著提高数据的检索效率。

 

-- 查询是否开启 自适应Hash索引,默认为 ON ,开启.
show variables like '%adaptive_hash_index%';

在这里插入图片描述

 

2、二叉搜索树

 
如果我们利用二叉树作为索引结构,那么磁盘的IO次数和索引树的高度是相关的。

二叉搜索树(二叉查找树)的特点

  • 一个节点只能有两个子节点,也就是一个节点度不能超过2.
  • 左子节点 < 本节点;右子节点 >= 本节点,比我大的向右,比我小的向左

 

二叉搜索树的查找规则:

二叉搜索树(Binary Search Tree),搜索某个节点和插入节点的规则一样,假设搜索插入的数值为key:

  • ① 如果 key 大于根节点,则在右子树中进行查找;
  • ② 如果 key 小于根节点,则在左子树中进行查找;
  • ③ 如果 key 等于根节点,也就是找到了这个节点,返回根节点即可。

在这里插入图片描述
二叉查找树可能退化成一条链表,查找数据的时间复杂度为O(N),如下图:
在这里插入图片描述

 

3、平衡二叉树(AVL树 )

 
       为解决二叉搜索树可能退化成链表的问题,就出现了平衡二叉树(Balanced Binary Tree),又称为 AVL 树(有别于 AVL 算法),它是在二叉搜索树的基础上增加了一些约束:平衡二叉树是一课空树,或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树

       常见的平衡二叉树包含:平衡二叉搜索树红黑树数堆伸展树一般平衡二叉树指的就是平衡二叉搜索树,搜索的时间复杂度为O(log2n),数据查询的时间主要依赖于磁盘的 I/O次数,当n 越大,查询越复杂。

在这里插入图片描述

       每访问一次节点就需要进行一次磁盘I/O操作,以上图示例来讲,需要进行4次I/O操作。虽然平衡二叉树的效率高,但是树的深度比较高时,也意味着磁盘I/O操作次数多,就会影响整体数据查询的效率。

 

4、B-Tree(B树)

 
       B树(Balance Tree)也就是多路平衡查找树,简写为 B-Tree(这里的横杠是连接符,而不是减号)。B-Tree 的高度远小于平衡二叉树的高度。B-Tree 关键点如下:

  • B-Tree 在插入、删除节点的时候,如果导致树不平衡,就通过自动调节节点的位置来保持树的自平衡

  • 关键字集合分布在整棵树中,如果一个磁块包括了x个关键字,那指针数为x+1,叶子节点和非叶子节点都存放数据。搜索有可能在非叶子节点结束。

  • 搜索性能等价于在关键字全集内做一次二分查找。

  • 对于一个M阶(每个节点最多可以包括M个子节点)的B-Tree,根节点的儿子数的范围是[2,M],且所有叶子节点位于同一层。

    在这里插入图片描述

假设查询关键字为 8 的数据。

  • ① 与根节点的关键字26 和 36 比较,8 小于26 ,取磁块1的P1指针向下级节点查找。
  • ② 按磁块1的P1指针找到磁块2,比对关键字 6 和 21,8大于6且小于21,取取磁块2的P2指针向下级节点查找。
  • ③ 按磁块2的P2指针找到磁块6,对比磁块6的关键字8和18,找到关键字8.

       在B-Tree 的搜索中,是把数据读取出来,然后在内存中进行比较,那比较的时间可忽略不计。读取磁盘块本身需要进行I/O操作,其消耗的时间比在内存中进行比较需要的时间较多,是数据查找用时的重要因素。B-Tree相比于平衡二叉树来说,磁盘I/O操作要少效率高,只要树的高度足够低,I/O次数足够少,就可以提高查询性能

 

5、B+Tree (B+树)

 

5.1、B+Tree 结构

 
       B+Tree 是一种多路搜素树,基于B-Tree做出了改进。主流的 DBMS都支持 B+Tree 的索引方式。B+Tree相比于B-Tree在查询效率、磁盘读写性能和范围查询方面更具优势,B+Tree 比 B-Tree 更适合文件索引系统
 
在这里插入图片描述

B+Tree和B-Tree的区别主要体现在以下三个方面:

  • 内部节点存储数据的方式:B-Tree的每个内部节点都存储数据,而B+Tree的内部节点并不存储数据,只作为索引使用,数据都存储在叶子节点上。因为B+Tree只在叶子节点存储数据,所以在查询时稳定性更好,且查询速度更快。

  • 叶子节点的链接方式:B+Tree的叶子节点之间通过指针连接,形成一个有序链表,便于进行范围查询。而B-Tree的叶子节点并没有相连,B-Tree 做范围查询时,需要通过中序遍历才能实现。在范围查询上,B+Tree 的效率比 B-Tree 高。

  • 磁盘读写性能:B+Tree相比于B-Tree,在磁盘读写性能上更有优势。这是因为B+Tree的内部节点并没有指向关键字具体信息的指针,所以其内部节点相对B-Tree更小,如果把内部节点和叶子节点存放在同一块磁盘内,那么盘块容纳的节点数目比B-Tree更多,一次性读入内存中的需要查找的关键字也就越多,相对来说IO读写次数也就降低了。
     

5.2、B+Tree 相关思考题

 
1、为了减少IO,B+Tree 索引树会一次性加载吗?

  • ① 数据库索引存储在磁盘上,如果数据量过大,必然会导致索引的大小也会很大,超过几个G.
  • ② 当利用索引查询时,是不可能将全部几个G 的索引数据,全都加载到内存中的。只能逐一加载每个磁盘页,因此磁盘页对应着索引树的节点。

 
2、B+Tree 的存储能力如何?为何说一般查找行记录,最多只需要 1~3次磁盘IO ?

InnoDB 存储引擎中数据页的大小默认为 16KB,一般表的主键类型为 int(占4个字节)或 bigint(占8个字节),指针类型一般也为4或8个字节,所以一个根节点或内节点的数据页(B+Tree中的一个节点)中大概存储 16KB/(8B+8B) = 1K 个键值。估算一下,就当K 的取值为10^3,那一个深度为3 的B+Tree 索引可以维护的数据为 10^3 * 10^3 * 10^2 = 1亿 条记录(这里假设一个叶子节点的数据页可以存 100 条行记录数据)。

实际情况中每个节点可能不会填充满,所以在数据库中,B+Tree 的高度一般都在 2~4 层。MySQL 的 InnoDB 存储引擎在设计时,将根节点常驻内存,也就是说查找某一键值的行记录时,最多只需要1~3次磁盘 IO 操作。

 
3、为什么说B+Tree 比 B-Tree 更适合实际应用中,操作系统的文件索引和数据库索引?

  • B+Tree 的磁盘读写代价更低

B+Tree 的内部节点,并没有指向关键字具体信息的指针,故其内部节点相对B-Tree 更小。通俗来说,就是B-Tree每个层级的节点都存放的行数据,但是B+Tree 只有在叶子节点存放行数据,内节点存放主键或非聚簇索引字段,所以一般情况来讲相同的数据体量,B+Tree的层级会低,磁盘IO操作次数更少,磁盘读写代价更低。

  • B+Tree 的查询效率更稳定

B+Tree 的叶子节点才会有用户记录行数据,所以任何关键字的查找,必须走一条从根节点到叶子节点的路,所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

 
4、Hash 索引和 B+Tree 索引的区别?

  • ① Hash 索引不能进行范围查询,B+Tree 可以。

  • ② Hash 索引不支持联合索引的最左原则(即联合索引的部分索引无法使用),B+Tree 可以。

  • ③ Hash 索引不支持 ORDER BY 排序,B+Tree 可以(B+Tree索引数据是有序的)。

  • ④ Hash 索引不支持模糊查询,B+Tree 使用LIKE进行模糊查询时, LIKE 后面后模糊查询(比如%结尾)可以起到优化作用。

  • ⑤ InnoDB 不支持哈希索引,但提供自适应 Hash 索引 (Adaptive Hash Index)。

 

5、Hash 索引和 B+Tree 索引是在键索引时,手动指定的吗?

对于MySQL而言,针对 InnoDB 和 MyISAM 存储引擎,都会默认采用 B+Tree 索引,无法使用 Hash 索引。InnoDB 提供的自适应 Hash 是不需要手动指定的。如果 Memory/Heap 和 NDB 存储引擎,是可以进行选择 Hash 索引的。

 

 
 
 
 
 
 
 
.

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

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

相关文章

EMQX内置Web管理控制台-Dashboard

一、Dashboard概述 EMQX Dashboard官网文档&#xff1a;https://docs.emqx.com/zh/enterprise/v5.1/dashboard/introduction.html 1、简介 EMQX 为用户提供了一个功能强大的内置管理控制台&#xff0c;即 EMQX Dashboard。通过这个控制台的 Web 界面&#xff0c;用户可以轻松监…

基于STM32闭环步进电机控制系统设计

**单片机设计介绍&#xff0c;1654基于STM32闭环步进电机控制系统设计&#xff08;仿真&#xff0c;程序&#xff0c;说明&#xff09; 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序文档 六、 文章目录 一 概要 基于STM32的闭环步进电机控制系统设计是…

劳动安全无小事,劳保安全鞋为您的足部安全保驾护航

安全生产责任重于泰山。日常说到劳动防护&#xff0c;人们往往先想到的是安全帽、工作服、安全带等身体与头部的防护&#xff0c;从而足部的伤害是较容易被人们所忽视的。其实脚部的防护至关重要&#xff0c;我们在日常工作中常见的足部伤害有&#xff1a;冲击、撞击伤害&#…

CSS中的栅格布局

CSS中的栅格布局 在写前端项目的时候&#xff0c;我之前一直习惯使用flex布局&#xff0c;flex布局写起来比较随心&#xff0c;几乎可以实现任意形式的页面布局。不过自从B占看到某位大佬的grid布局后&#xff0c;发现布局居然还可以这么玩&#xff0c;正好自己在写一个vue3的…

中兴再推爆款,双2.5G网口的巡天AX3000Pro+仅需299元

10月30日消息,中兴新款路由器中兴巡天AX3000Pro将于10月31日20:00正式开售,当前可在天猫、京东及红魔商城进行预约,首发价格299元。 据了解,中兴巡天AX3000Pro是中兴智慧家庭推出的巡天系列新品,也是当前市场上唯一一款300元价位内配备双2.5G网口的路由器。 中兴巡天AX3000Pro…

客户端与服务端实时通讯(轮询、websocket、SSE)

客户端与服务端实时通讯 背景 在某些项目中&#xff0c;某些数据需要展示最新的&#xff0c;实时的&#xff0c;这时候就需要和服务端进行长时间通讯 方案 对于数据实时获取&#xff0c;我们一般会有4种方案&#xff1a; 1.短轮询&#xff1a;使用浏览器的定时器发起http请…

三叠云督察督办解决方案:助力企业高效决策与执行

信息时代的到来&#xff0c;企业面临着日益增长的管理挑战。高竞争的商业环境中&#xff0c;如何实现高效的决策和执行成为了企业迫切需要解决的问题。在现代企业管理中&#xff0c;督察督办工作的重要性也日益凸显。 然而&#xff0c;传统的督察督办模式存在诸多问题&#xff…

JavaScript组合模式

JavaScript组合模式 1 什么是组合模式2 宏命令3 示例&#xff1a;扫描文件夹4 引用父对象 1 什么是组合模式 组合模式是一种结构型设计模式&#xff0c;用于将对象组合成树形结构&#xff0c;并使客户端能够统一处理单个对象和组合对象。它通过使用继承和组合两个概念&#xf…

题目描述:输入数字,第一行为数组的大小,第二行为数组的值。求其中相邻两个数字相差不大于8的最大片段的长度。

题目描述&#xff1a; 输入数字&#xff0c;第一行为数组的大小&#xff0c;第二行为数组的值。求其中相邻两个数字相差不大于8的最大片段的长度。 示例1&#xff1a; 输入&#xff1a;91 2 4 6 12 2 8 6 4 输出&#xff1a;5示例2&#xff1a; 输入&#xff1a;101 4 5 6 2…

数据清洗(1)--数据查缺补漏

前言 之前使用scikit 进行一些基础模型的选择&#xff08;SVM支持向量机&#xff0c;LR算法&#xff0c;KNN&#xff0c;SGD&#xff0c;Bays贝叶斯&#xff0c;决策树&#xff0c;随机森林&#xff09;&#xff0c;创建&#xff0c;训练&#xff08;测试集验证集&#xff09;…

Redis测试新手入门教程

在测试过程中&#xff0c;我们或多或少会接触到Redis&#xff0c;今天就把在小破站看到的三丰老师课程&#xff0c;把笔记整理了下&#xff0c;用来备忘&#xff0c;也希望能给大家带来亿点点收获。 主要分为两个部分&#xff1a; 一、缓存技术在后端架构中是如何应用的&#…

C语言实现求某班学生的平均成绩和均方差

完整代码&#xff1a; /* 已知求成绩的平均值和均方差公式为&#xff1a;&#x1d44e;&#x1d463;&#x1d452; ∑&#x1d460;&#x1d456;/n , &#x1d451;&#x1d452;&#x1d463; √(∑ (&#x1d460;&#x1d456;−&#x1d44e;&#x1d463;&#x1d45…

Android开发知识学习——HTTPS

文章目录 定义HTTPS连接HTTPS 连接建立的过程课后题 定义 HTTP Secure / HTTP over SSL / HTTP over TLS SSL&#xff1a;Secure Socket Layer -> TLS Transport Layer Security 定义&#xff1a;在HTTP之下增加的一个安全层&#xff0c;用于保障HTTP的加密传输 本质&…

Python 自动化测试全攻略:五种自动化测试模型实战详解!

随着移动互联网的发展&#xff0c;软件研发模型逐步完善&#xff0c;软件交付质量越来越受到软件公司的重视&#xff0c;软件测试技术特别是自动化测试技术开始在软件系统研发过程中发挥着越来越重要的作用。 与传统的手工测试技术相比&#xff0c;自动化测试具备了良好的可操…

Mysql进阶-索引篇(下)

SQL性能分析 SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff0c;通过sql语句的访问频次&#xff0c;我们可…

技术视角下的跑腿小程序开发:关键挑战和解决方案

跑腿小程序作为连接服务提供者和用户的桥梁&#xff0c;面临着诸多技术挑战。本文将聚焦于技术层面的关键挑战&#xff0c;并提供解决方案&#xff0c;以帮助开发者应对技术上的复杂问题。 1. 实时性与性能挑战 挑战&#xff1a; 跑腿小程序需要实时地匹配订单、更新状态和提…

【java学习—十】操作集合的工具类Collections(8)

文章目录 1. 操作集合的工具类&#xff1a; Collections2. 应用3. 查找、替换3.1. max 与 min3.2. 根据Comparator返回max(min) 3.3. frequency 与 replaceAll4. 同步控制 1. 操作集合的工具类&#xff1a; Collections Collections 是一个操作 Set 、List 和 Map 等集合的工具…

从LLM到AIGC,开启AI时代寻宝之旅!

引言 还记得《头号玩家》中男主人公赢得游戏的方式吗——在游戏中漫无目的地闲逛&#xff0c;然后发现彩蛋&#xff0c;获得胜利。 在人工智能领域&#xff0c;有一种新奇性搜索原则的实验&#xff0c;使得机器研究的成功之路恰似寻找彩蛋的道路。比如在不设定“出门”目标的情…

为什么会被【禅道】工具的公司踢出QQ群的反思…………

周末备份Gitlab的代码库&#xff0c;把Gitlab更新到了最新的16.5。顺带看了禅道官网出了最新版本18.8。但是禅道的升级更新并不顺利…………。 先说一下为什么用禅道这个工具&#xff1a; 再使用禅道这个工具前&#xff0c;使用过的工具有QC(Quality Center)、jira&#xff0…