为什么数据库索引数据结构使用B+树,而不使用xxx?

简介: 为什么数据库索引数据结构使用B+树,而不使用xxx?

这个问题其实还是很有趣的,我在上一篇文章中,写了:

1、为什么数据库索引不能用二叉排序树;

2、为什么数据库索引不能用红黑树;

本篇文章增加了:

1、为什么不能使用哈希表;

2、为什么不能使用B-树;

3、为什么能使用B+树。

一、为什么数据库的索引不能用二叉搜索树?

根据上面的演示,看着二叉搜索树也是可以的呀,也挺快嘛。

但是为什么用在数据库底层不合适呢?这也是面试时常问的。

我们可以演示一下:

https://www.cs.usfca.edu/~galles/visualization/BST.html

我们假设我们给Col1加上索引,那么依次对二叉搜索树插入:1、2、3、4、5、6、7;

可以看到退化成了一个链表的形式。

当我们查询7的话,时间复杂度就变成了单链表一样了。

从大到小也是:

总结如下:

  • 如果数据库底层使用二叉搜索树的话,遇到数据为极端的情况下会退化成单链表,所以不太合适;

可以想象一下,如果我们给自增的一列使用二叉搜索树的索引数据结构的话,是不是就很倒霉了。这就是极端的情况,都在一边。

二、为什么红黑树不适合数据库索引?

红黑树又叫:二叉平衡树

红黑树作为Java开发人员应该很耳熟吧,JDK8中的HashMap中的底层数据结构就用到了红黑树。

这么牛逼的JDK中都用到了红黑树,为什么数据库中的索引数据结构不太适合呢?

还是上面那个假设,假设我们给Col1加上红黑树的索引。

过程如下动态演示:

如果我们执行:

select * from table1 where Col1 = 7;

动态演示如下:

可以看到,我们一共查询了4次就查到了。与没加这个索引之前还是有比较大的效果的,至少没有全部扫描。

总结:

通过观察可以看到,每次插入几乎都会去调整这颗二叉树,保持高度是平衡的。

如果数据量非常大的话,也是非常耗时的,所以红黑树也是不太合适。

三、为什么不能使用Hash数据结构作为索引的数据结构呢?

当你点进这篇文章的时候,肯定对于Hash表是熟悉的了。

Hash表的话,简单点说有这么几个特点:

  • 1、数据插入的位置由哈希值决定,顺序无序的;
  • 2、插入很快;
  • 3、查找也很快;

我们拿一组数据来插入哈希表试试:

100、13、101、14、103、109

我们使用https://www.cs.usfca.edu/~galles/visualization/ClosedHash.html来动态模拟Hash表;

为了表现出来Hash表为什么不适用与数据库,我们顺序插入准备好的数据:

动态演示如下:

结果如下:

1、

我们在数据库中经常使用sql来查询一个范围的数据例如:

select * from t where id < 15;

我们知道哈希表是无序的,所以就凭借这一点,就比较困难。

心里应该也有数了,哈希表是肯定不可以的。

2、

从插入数据的动态演示中可以看到,100和13的哈希值都是13。

那么就会向后移动(这也是哈希表解决冲突的一种方式)。

例如:我们先插入100,然后插入13;

我们想查找13的话,就会比较慢了。

两个数可能体现不出来,1万个?10万个?100万个数呢?可想而知,就相当于进行了全表扫描。

所以,哈希表总体来说,不合适。

四、为什么不能使用B-树

B-Tree就是B树,不叫B减树。

我们继续来模拟:

https://www.cs.usfca.edu/~galles/visualization/BTree.html

插入1-10,10个数后:

B树确实解决了我们上面所说的哈希表的查找范围的问题。

我们执行下列sql:

select * from t where id > 5;

(1)首先查找到5

查找路径为:4–>6–>5;

(2)然后返回上一层查找到6

(3)然后查找到6

(4)…

可以看到会有一个回旋的过程,随着数据量的增长,回旋的过程也就越多,那么所浪费的时间也就越多。

五、为什么能使用B+树

我们使用这个来模拟:

https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

构造一个1-10的数的B+树;

先来介绍以下这颗树:

一共分为两部分,叶子节点和非叶子节点。

  • 叶子节点是由链表实现的,凡是插入的数据,全都链接在一起。
  • 非叶子节点只存key;
  • 叶子节点即存key又存value;

key:0-10这个数字;

value:0-10的数字的地址。

解决了B树中回旋查找的问题。查找效率也整体提高了。

例如:

select * from t where id > 5;

看下图:

可以看到,先查找非叶子节点5、然后7、然后6,最终查找到叶子节点5。

查找到之后,就可以顺序取出了,就不必继续回去上一层了。

目录
相关文章
|
1月前
|
数据库 索引
深入探索数据库索引技术:回表与索引下推解析
【10月更文挑战第15天】在数据库查询优化的领域中,回表和索引下推是两个核心概念,它们对于提高查询性能至关重要。本文将详细解释这两个术语,并探讨它们在数据库操作中的作用和影响。
50 3
|
1月前
|
数据库 索引
深入理解数据库索引技术:回表与索引下推详解
【10月更文挑战第23天】 在数据库查询性能优化中,索引的使用是提升查询效率的关键。然而,并非所有的索引都能直接加速查询。本文将深入探讨两个重要的数据库索引技术:回表和索引下推,解释它们的概念、工作原理以及对性能的影响。
60 3
|
25天前
|
数据库 索引
数据库索引
数据库索引 1、索引:建立在表一列或多列的辅助对象,目的是加快访问表的数据。 2、索引的优点: (1)、创建唯一性索引,可以确保数据的唯一性; (2)、大大加快数据检索速度; (3)、加速表与表之间的连接; (4)、在查询过程中,使用优化隐藏器,提高系统性能。 3、索引的缺点: (1)、创建和维护索引需要耗费时间,随数据量增加而增加; (2)、索引占用物理空间; (3)、对表的数据进行增删改时,索引需要动态维护,降低了数据的维护速度。
33 2
|
2月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
69 3
Mysql(4)—数据库索引
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
192 1
|
29天前
|
存储 关系型数据库 数据库
Postgres数据库BRIN索引介绍
BRIN索引是PostgreSQL提供的一种高效、轻量级的索引类型,特别适用于大规模、顺序数据的范围查询。通过存储数据块的摘要信息,BRIN索引在降低存储和维护成本的同时,提供了良好的查询性能。然而,其适用场景有限,不适合随机数据分布或频繁更新的场景。在选择索引类型时,需根据数据特性和查询需求进行权衡。希望本文对你理解和使用PostgreSQL的BRIN索引有所帮助。
35 0
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
78 0
|
26天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
34 1
|
28天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
39 4
|
1月前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
100 2