具体算法8 - 索引的方方面面

2020-04-19  本文已影响0人  天命_风流

本章关键词

索引、查找、需求

索引是软件编写中非常重要的技术,今天这一节我们就回顾一下那些可以用于索引的数据结构,并分析这些数据结构作为索引可以支撑怎样的功能,性能又如何。

为什么需要索引

我粗略地将程序的执行过程分为以下三个步骤:输入-处理-输出。在这三个步骤中,输入和输出对应数据的存储,处理对应计算。

数据的存储要依赖特定的数据结构,不同的数据结构会有不桶的增、删、改、查,的性能。

当存储的数据非常庞大的时候,我们就需要特别关注它们的执行性能了,而影响性能的非常重要的一点,就是索引。索引,通俗地理解,就是在一组数据中寻找到自己需要的数据子集。

索引的需求定义

分析需求,要从功能性需求非功能性需求两个方面来分析,对于索引来说,它们的需求分别如下:

1.功能性需求

数据是格式化数据还是非格式化数据? 对于非格式化数据,我们一般需要做预处理,提取出查询关键词,对关键词构建索引。

数据是静态数据还是动态数据? 静态数据通常不涉及频繁的 增、删、改 操作,所以只需要考虑查询效率即可。对于动态数据,我们不仅要考虑查询,也要考虑数据更新带来的索引更新。

索引存储在内存还是硬盘? 内存的查询速度比硬盘快很多,但是容量有限。硬盘则反之。通常,我们倾向把“小”索引放到内存中,把较“大”的索引放到硬盘中。当然,你可以考虑另一种情况:索引分别存在于两者中。

单值查找还是区间查找?许多时候我们不只是要查找单个数据,还要按范围进行索引。

单关键词查找还是多关键词组合查找?单关键词的查找相对简单,对于多关键词查找,要区分不同的情况。对于结构化的数据,我们可以实现针对多个关键词的组合建立索引(这可能会耗费大量空间);对于非结构化数据,我们可以分别进行单关键词查找,然后通过集合操作计算出查询结果。

2.非功能性需求

索引对存储空间的消耗不能过大

在考虑查询效率的同时,我们还要考虑索引的维护成本 对动态的数据集合构建的索引,我们需要考虑索引的维护成本,这种维护成本不能过高,否则会影响到数据操作的性能。

构件索引常用的数据结构

在我们学习过的数据结构中,散列表、红黑树、跳表、B+树 等可以作为动态数据的索引。除此之外,位图、布隆过滤器可以作为辅助索引。有序数组也可以用作静态数据的索引

散列表:散列表的增删改查的性能非常好。但是你需要注意装载因子对性能的影响。

红黑树:红黑树是一种常用的平衡二叉查找树,数据的添加、删除、查找的时间复杂度都是O(logn)。

B+ 树 相对于红黑树,B+树 要使用更多的空间构建索引,所以通常我们将它放在硬盘中。为了减轻文件 IO 操作带来的影响,我们会将二叉树改为 m 叉树,以降低树的高度。它支持范围索引

跳表 跳表支持快速添加、删除、查找数据。而且,我们可以灵活调整索引节点的个数和数据个数的比例,平衡内存空间和查询效率的需求。相比于红黑树,它还支持范围索引

位图和布隆过滤器 这两个数据结构比较节省内存空间,且可以承担一定程度的索引功能,所以我们可以使用它作为辅助索引。例如,布隆过滤器在判定数据不存时不会出错,我们可以利用这个特性加速查询。

有序数组有序数组只能用于静态数据的索引,我们可以使用二分查找快速地定位数据。

各种数据结构的组合学习一定要灵活,基础的数据结构不多,但是我们可以通过组合使用他们实现更多样的功能。例如,使用“散列表 + 有序链表”可以一定程度上实现范围索引。

总结

在这里,我把对于数据结构和索引的思考总结如下:


以上就是关于索引的全部内容,希望能够帮你打开思路

注:本文章的主要内容来自我对极客时间app的《数据结构与算法之美》专栏的总结,我使用了大量的原文、代码和截图,如果想要了解具体内容,可以前往极客时间

上一篇下一篇

猜你喜欢

热点阅读