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

本章关键词

索引、查找、需求

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

为什么需要索引

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

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

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

索引的需求定义

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

1.功能性需求

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

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

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

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

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

2.非功能性需求

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

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

构件索引常用的数据结构

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

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

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

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

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

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

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

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

总结

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

  • 数据的存储,在底层只有两种形式:连续空间存储 和 零散空间存储,这两种形式对应了两种最基本的数据结构:数组 和 链表

  • 使用这两种数据结构存储数据的空间利用率是最高的,但是如果想要实现更加快速的查找,我们就需要使用额外的操作,这两种操作是:用额外计算获取数据地址 和 用额外空间保持一种方便查找的结构。

  • 用额外的计算获取数据地址,这种思路只能用于数组,因为数组的下标可以计算内存地址。具体应用如下:
    1.使用数组下标进行数据的随机访问,这也是数组的杀手锏
    2.通过对数据的计算确定数据应该存放的位置,这就是散列表,这种计算方法就是哈希函数

  • 用额外的空间保持方便查找的结构,这种思路用于“使用零散空间存储数据的情况”,你仔细思考,跳表、红黑树、B+树 是不是都是这种思路的产儿?
    1.跳表通过设置额外的节点索引,实现了加快数据查询的功能。
    2.红黑树、B+树 通过树这种结构用不同孩子保存了不同数据间的关系

  • 不同数据结构的组合可以实现更多功能。

  • 如果想实现范围索引,最好的办法是使用有序链表,我们通过某种方法,找到数据范围中的起始结点,然后通过有序链表依次输出范围内的结点,直到数据超出范围,这里有几个现成的例子:
    1.跳表:通过额外的结点找到有序链表的起始结点,然后依次输出
    2.B+树:通过查找叶子节点定位有序链表的起始节点,然后依次输出


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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容