索引数据结构的前生今世

289 阅读3分钟

在使用数据库时,很多情况下,我们需要提高查询速率,这时候我们通常会为这个表来 创建索引,实际上就相当于给一本书加入了目录。索引的实现方式随着发展,现在普遍应用的是b+树。为什么呢?b+树有什么优点呢?还请听我慢慢道来。

索引的发展历程主要分为四个阶段:哈希 --> 二叉树 --> 平衡二叉树 --> b树 --> b+树

哈希结构

就哈希而言,大家应该都是比较熟悉的。可以说hashmap的实现就是哈希结构的一个经典案例。在这儿我们可以理解为将要索引的表内容引入到hashmap中,在查找时,直接使用哈希函数对要查询的值进行计算得到位置,就可以直接找到对应的数据。时间复杂度为O(1)。但是他也有一个致命的缺点,只适用于等值查询的情况。当遇到范围查找、排序等操作时,时间复杂度直接掉为O(n)。而在数据库中,范围查找等操作是普遍存在的。哈希结构的索引便显得较为鸡肋,在mysql5.5以后版本的默认存储引擎InnoDB中已经不支持这种索引结构了。

二叉树

先简单回顾一下数据结构中二叉树的知识,二叉树有两个特点:

  • 一个节点最多有两个字节点。
  • 左子节点小于本节点,右子节点大于本节点。

在二叉树里面,对于一个节点的查找与他所在的深度有关,深度越深,查找次数越多。 该二叉树有一种最坏的情况,当节点是递增的,该二叉树就退化成了链表,查找时间复杂度从O(logn)到了O(n)。

平衡二叉树

平衡二叉树解决了二叉树的退化问题,在每次插入新节点的时候都会进行调整。但是平衡二叉树作为索引并不完美,因为查找次数与节点的深度有关,当数据量越来越大时,树的深度也会越来越大,查找次数自然变得更大。

我们使用索引的初衷是啥?

提高查询速率.

为啥提高?

肯定是数据量太大查的慢呀。

数据库:你群攻技能威力太小。你很出色,但是不好意思,不太合适。

平衡二叉树:emmm~

b-树

为了让一个查询尽量少地读磁盘,就必须让查询过程访问尽量少的数据块,那么,我们就不应该使用二叉树,而是要使用“N叉”树。这里,“N叉”树中的“N”取决于数据块的大小。这样一棵树就由高瘦变成了矮胖。到这里,b-树已经是一个非常出色的索引数据结构了。

b+树

前面说过mysql5.5以后版本的默认存储引擎InnoDB中使用的是b+树。“+”就是plus么。b-树的增强版。增强在哪儿呢?b+树将所有的节点数据放到了叶子节点,并将叶子结点连起来组成了一个链表。

b+树
这样大大提高了范围查找的速率,而且遍历整棵树更加的方便。还有一点,非叶子节点不存储数据了,磁盘块空间可以省出来存放更多的节点。使得上文中的N变得更大。


不管是哈希还是有序数组,或者N叉树,它们都是不断迭代、不断优化的产物或者解决方案。