MySQL~不同数据结构对索引的友好程度(Hash、二叉搜索树、AVL树、B-树、B+树)

本文探讨了选择数据库索引结构时,为何B+树通常优于其他数据结构如Hash表、二叉搜索树和AVL树。B+树的磁盘I/O效率高,适合大规模数据,且其节点结构设计减少了磁盘读取次数。重点分析了B-树和B+树的区别,以及B+树在文件索引和数据库索引中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.选择标准

索引选数据结构只有一个标准:磁盘IO次数,越少越好

索引是存储在外部磁盘上的,对于关系型数据库,当数据量比较大的时候,索引有可能达到几个G甚至更多,不可能全部加载完,只能逐一加载,每次加载都会耗时,所以加载次数越少越好

2.各种数据结构分析

2.1可以是Hash表吗?

不可以

  • Hash是通过某种确定的算法将输入变输出,相同的输入总会得到相同的输出
  • Hash中像HashMap,增删查改的平均都是O(1),单从效率方面是比B+树快好几倍
  • 哈希在处理数据相等时效率非常高

那为什么不选Hash?

  • 原因1:Hash索引只支持等于、不等于、in查询.如果进行范围查询,哈希的复杂度会退化成O(n),而树索引仍然高效O(log2N)
  • 原因2:哈希存储数据无序,因为哈希值无序,所以存储的数据也无序,如果使用ORDER BY查询,数据会重新排序
  • 原因3:联合索引时,Hash会将几个索引值合并计算,无法对单独的一个或几个索引进行查询
  • 原因4:如果索引列的重复值比较多(比如性别、年龄),Hash会发生哈希冲突,导致效率大大降低,可能会O(n)

Hash索引的适应场景
虽然树索引使用范围更广,但也有一些场景使用Hash索引效率更高,比如键值型数据库中,Redis存储的核心就是哈希表

Innodb本身虽然不支持哈希索引,但是提提供自适应哈希Adaptive Hash Index),如果某个数据经常被访问,就会将这个数据放入Hash表中,下次访问可以直接取出,这样树索引也有了哈希的优点。

2.2 可以是二叉搜索树或者红黑树吗?

不可以

  • 二叉搜索树每个节点只能有两个子节点,即度为2,且左节点<根节点<右节点

  • 最基础的二叉搜索树(Binary Search Tree)查找规则如下:如果key大于根节点,去右子树;如果key小于根节点,去左子树;如果等于根节点,返回根节点;
    正常情况O(log2N):
    在这里插入图片描述
    特殊情况O(n):
    深度过大,退化成线性,类似链表
    在这里插入图片描述
    为什么不可以?

  • 二叉搜索树的平均查找效率是O(logN)

  • 如果数据很多的话,二叉搜索树最多俩分支,所以树的深度会很大,查找效率其实不高

  • 如果是范围查找还需要对二叉树进行中序遍历(二叉树的中序遍历有序),和上面的链表一样是O(N)不高效

2.3 可以是AVL树吗?

本质可以,但为了更高的效率不选它

  • 2叉树时,如果数据非常大,深度依然很大,效率并不高
  • 拿来当索引时,尽量往N叉树方向发展

AVL树

  • AVL树又被称为平衡二叉搜索树(Balanced Binary Tree),特点:它可以是一颗空树或它的左右两个子树的高度差小于1,并且左右子树都是平衡树.

虽然不会退化成O(N),但是数据非常多时,树的深度依然很高,如下图:
在这里插入图片描述
如何解决这个问题?
可以将2叉树变成N叉树,比如相同数据情况下,将2叉树变成3叉树:
在这里插入图片描述
总结:
二叉树或者AVL树可以用来作为数据库索引,但是尽量往N叉树的方向发展,降低树的高度,才能更符合索引的查找特性.

可以用树作为索引的数据结构,但是树越“矮胖”越好.

2.4 可以是B-树吗?

本质可以,但是为了更高的效率不选它

B-树和二叉树的差异

  • 结点不再限于2个分支,可以有n个分支
  • 结点不只存1个数据,可以存多个数据
  • 节点存储数据个数和度有关 度=存储数据个数+1
  • 在每个节点中查找时,不再限于2分查找,可以是N分查找,效率更高
  • 在非叶子节点中也存有数据,如果和非叶节点中的数据相同,可以直接返回

B-树

  • B-树(Balance-Tree),多路平衡查找树,一个节点最多可以有m个节点,m就称为B-树的阶,每个节点中包括关键字子节点的指针,关键字中附带数据.对于一个100阶的B-树,在第3层就可以储存100万的索引数据,在大量索引数据的情况下,B-树是非常合适的.

B-树的特性

  • 根节点最少有2个节点;
  • 每个节点最多可以有m个节点;
  • 除了根 叶子节点外,其余节点最少要有m/2个节点
  • 所有节点的子节点个数可以不相同,但最少m/2
  • 叶子节点必须在同一层中
  • 增加和删除节点时,如果不平衡,B树会自动调整节点的位置来保持平衡(旋转)
  • 关键字遍布全树,即叶子和非叶子节点中都存放数据
  • 每一次搜索相当于对关键字进行一次二分查找
    在这里插入图片描述
2.5 可以是B+树吗?

可以,官方推荐+默认,真实的索引结构

  • B+树是B-树的进阶,本质上也是多路搜索树
  • B+树适合文件索引场景

B+树和B-树的差异

  • B+树有几个分支就有几个关键字,而B-树 分支=关键字+1
  • B+树父节点的关键字在子节点中都能找到,并且一般父节点的关键字是子节点关键字中最大或者最小的那个
  • B+树只有叶子节点保存数据,而B-树叶子 非叶子节点都保存数据
  • B+树所有关键字都在叶子节点出现,而B-树只出现部分关键字

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

1.B+树的磁盘读写次数少
B+树的节点中不含有指针,比B-树的节点小,如果把左右的关键字段放入节点中,该节点容纳的关键字的数量就更多,一次性读入内存的关键字就越多,相对的查找次数就越低.
2.B+树的查询效率更稳定
B+树的所有的数据都存放在叶子节点,每次查询数据的路径长度差不多,查询效率相当,而B-树在非叶子节点中也存放数据,不同数据查询的路径长度不同,查询效率就不同,所以稳定性差一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值