数据结构与算法之美
王争
前 Google 工程师
283752 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 81 讲
基础篇 (38讲)
数据结构与算法之美
15
15
1.0x
00:00/00:00
登录|注册

50 | 索引:如何在海量数据中快速查找某个数据?

在考虑索引查询效率的同时,我们还要考虑索引的维护成本
不管是存储在内存中还是磁盘中,索引对存储空间的消耗不能过大
单关键词查找还是多关键词组合查找
单值查找还是区间查找
索引存储在内存还是硬盘
数据是静态数据还是动态数据
数据是格式化数据还是非格式化数据
有序数组
布隆过滤器
位图
跳表
B+树
红黑树
散列表
非功能性需求
功能性需求
课后思考
总结引申
构建索引常用的数据结构
索引的需求定义
索引

该思维导图由 AI 生成,仅供参考

在第 48 节中,我们讲了 MySQL 数据库索引的实现原理。MySQL 底层依赖的是 B+ 树这种数据结构。留言里有同学问我,那类似 Redis 这样的 Key-Value 数据库中的索引,又是怎么实现的呢?底层依赖的又是什么数据结构呢?
今天,我就来讲一下索引这种常用的技术解决思路,底层往往会依赖哪些数据结构。同时,通过索引这个应用场景,我也带你回顾一下,之前我们学过的几种支持动态集合的数据结构。

为什么需要索引?

在实际的软件开发中,业务纷繁复杂,功能千变万化,但是,万变不离其宗。如果抛开这些业务和功能的外壳,其实它们的本质都可以抽象为“对数据的存储和计算”。对应到数据结构和算法中,那“存储”需要的就是数据结构,“计算”需要的就是算法。
对于存储的需求,功能上无外乎增删改查。这其实并不复杂。但是,一旦存储的数据很多,那性能就成了这些系统要关注的重点,特别是在一些跟存储相关的基础系统(比如 MySQL 数据库、分布式文件系统等)、中间件(比如消息中间件 RocketMQ 等)中。
“如何节省存储空间、如何提高数据增删改查的执行效率”,这样的问题就成了设计的重点。而这些系统的实现,都离不开一个东西,那就是索引。不夸张地说,索引设计得好坏,直接决定了这些系统是否优秀。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了在海量数据中快速查找某个数据的重要性和技术挑战。从索引的概念出发,介绍了设计索引时需要考虑的功能性和非功能性需求,包括数据类型、数据动态性、存储介质、查询类型等方面。通过对MySQL数据库索引和Redis Key-Value数据库索引的实现原理和底层数据结构进行分析,读者可以直观地理解索引的作用和设计的重要性。文章还介绍了常用的构建索引的数据结构,如散列表、红黑树、跳表、B+树等,以及位图、布隆过滤器和有序数组的辅助索引应用。通过深入浅出的方式,本文为读者提供了一份全面的索引技术概览,使读者对索引技术有了清晰的认识,了解其在海量数据处理中的重要性和复杂性。文章强调了架构设计离不开数据结构和算法,对于想成长为优秀的业务架构师、基础架构师的读者来说,数据结构和算法的根基至关重要。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《数据结构与算法之美》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(41)

  • 最新
  • 精选
  • Jerry银银
    今天音频朗读帅哥把MySQL读成了 my s q l ,早上起来听音频,萌了\(//∇//)\

    编辑回复: 官方读法就是 S Q L 哈

    2019-01-21
    7
    14
  • 万里有云
    把数据的关键词(查询用的)抽取出来,组织成有序数组。如果关键词是整型,那索引就是整形数组,关键词是字符串,那索引就是字符串指针数组吗?

    作者回复: 是的

    2019-04-12
    6
  • Jerry银银
    我对索引的理解 ------------ 索引真是个好东西。索引的英文名字叫:index,记住这个英文单词,会让我们更容易记忆和联想它到底是什么。在实际的编程中,index这个单词,真是到处可见。例如:数组的下标就是index 如果用一句话描述“索引”的作用,那会是什么?我想是这样:索引是用来辅助查找,用计算机专业术语叫:Addressing(寻址) 现实世界中,我们的查找会存在两种场景: 1. 从局部信息,查询与其相关的整体信息 2. 从整体信息中查询局部信息 怎么理解呢? 搜索引擎需要查询一个网页中是否存在某个关键词以及通过某个关键词查询包含它的所有网页。 索引的应用 -------- 正是因为计算机大部分工作都是在Addressing,所以,在计算机中,索引到处存在。小到操作系统虚拟内存到真实内存的映射,就是索引嘛,大到分布式系统、网络,都是这个原理。 以上,我对索引的理解有点“广义”。我觉得数据结构和算法如此重要,它体现计算机精髓的地方便在于此。
    2019-01-21
    6
    138
  • freeland
    es中的单排索引其实用了trie树,对每个需要索引的key维护了一个trie树,用于定位到这个key在文件中的位置, 然后直接用有序列表直接去访问对应的documents ,区块链拿以太坊来说吧,存储用的leveldb,数据存储用的数据结构是帕特利夏树,是一种高级的trie树,很好的做了数据的压缩, 消息中间件像kafka这种,会去做持久化,每个partition都会有很多数据,会有大量数据存储在磁盘中,所以每个partition也会有个索引,方便去做快速访问
    2019-01-21
    63
  • 大毛
    谈一谈自己对数据结构和索引的理解: - 数据的存储,在底层只有两种形式:连续空间存储 和 零散空间存储,这两种形式对应了两种最基本的数据结构:数组 和 链表 - 使用这两种数据结构存储数据的空间利用率是最高的,但是如果想要实现更加快速的查找,我们就需要使用额外的操作,这两种操作是:用额外计算获取数据地址 和 用额外空间保持一种方便查找的结构。 - 用额外的计算获取数据地址,这种思路只能用于数组,因为数组的下标可以计算内存地址。具体应用如下: 1.使用数组下标进行数据的随机访问,这也是数组的杀手锏 2.通过对数据的计算确定数据应该存放的位置,这就是 散列表,这种计算方法就是哈希函数 - 用额外的空间保持方便查找的结构,这种思路用于“使用零散空间存储数据的情况”,你仔细思考,跳表、红黑树、B+树 是不是都是这种思路的产儿? 1.跳表通过设置额外的节点索引,实现了加快数据查询的功能。 2.红黑树、B+树 通过树这种结构用不同孩子保存了不同数据间的关系。 - 不同数据结构的组合可以实现更多功能。 - 如果想实现范围索引,最好的办法是使用有序链表,我们通过某种方法,找到数据范围中的起始结点,然后通过有序链表依次输出范围内的结点,直到数据超出范围,这里有几个现成的例子: 1.跳表:通过额外的结点找到有序链表的起始结点,然后依次输出 2.B+树:通过查找叶子节点定位有序链表的起始节点,然后依次输出
    2020-04-19
    6
    40
  • 往事随风,顺其自然
    可以讲讲es 到排序索引结构原理和数据结构?
    2019-01-22
    20
  • 在路边鼓掌的人
    昨天刚学了操作系统的多级页表,应该是比较经典的索引了😂
    2019-01-22
    13
  • 海贼王
    从评论可以看出能坚持到这里的人不多,不过也不绝对,因为有些坚持到这里的人可能因为某些原因没有发表评论。不过还是很感谢老师的,从这个课程中,我体会到了数据结构的用处。之前有人说数据结构在平常的开发中没有用,当时我表示认同。现在看来,这句话也不完全正确。不同层次的人看问题的思路不同,结果也南辕北辙。
    2019-11-29
    12
  • 注定非凡
    为什么需要索引? (1)在实际的软件开发工作的本质都可以抽象为“对数据的存储和计算”。对应到数据结构和算法中,那“存储”需要的就是数据结构,“计算”需要的就是算法。 (2)对于存储的需求,功能上无外乎增删改查。当存储的数据很多,性能就会成为这些系统要关注的重点,特别是在存储相关的基础系统、中间件中。 (3)“如何节省存储空间、如何提高数据增删改查的执行效率”,解决这样的问题离不开索引 索引的需求定义 对于系统设计需求,一般可以从功能性需求和非功能性需求两方面来分析 1. 功能性需求 (1)数据是格式化数据还是非格式化数据? 构建索引的原始数据,可分为两类: * 一类是结构化数据,如MySQL 中的数据; * 一类是非结构化数据,如搜索引擎中网页。非结构化数据,一般需要预处理,提取出查询关键词,对关键词构建索引。 (2)数据是静态数据还是动态数据? * 如果是一组静态数据,在构建索引时只需考虑查询效率 * 动态数据构建索引,不仅要考虑索引的查询效率,在原始数据更新的同时,还需要动态地更新索引 (3)索引存储在内存还是硬盘? * 当数据量小时,索引可以存储在内存中。 * 原始数据量很大时,对应的索引可能也会很大。内存有限,可能需要将索引存储在磁盘中。 * 第三种情况:一部分存储在内存,一部分存储在磁盘,这样可以兼顾内存消耗和查询效率。 (4)单值查找还是区间查找? * 所谓单值查找,也就是根据查询关键词等于某个值的数据。 * 所谓区间查找,就是查找关键词处于某个区间值的所有数据。不同的应用场景,查询的需求会多种多样。 (5)单关键词查找还是多关键词组合查找? * 对于单关键词的查找,索引构建起来相对简单。 * 多关键词查询要分多种情况: A:像 MySQL 这种结构化数据的查询,可以实现针对多个关键词的组合,建立索引; B:像搜索引擎这样的非结构数据的查询,可以针对单个关键词构建索引,然后通过集合操作,如求并集、求交集等,计算出多个关键词组合的查询结果。 不同的场景,不同的原始数据,对于索引的需求也会千差万别 2. 非功能性需求 (1)不管是存储在内存中还是磁盘中,索引对存储空间的消耗不能过大。 * 如果存储在内存中,索引对占用存储空间的限制就会非常苛刻 * 如果存储在硬盘中,也不能掉以轻心,因为有时索引对存储空间的消耗会超过原始数据 (2)在考虑索引查询效率的同时,还要考虑索引的维护成本。 * 基于动态数据集合构建的索引要考虑索引的维护成本。因为在原始数据动态增删改的同时,也需要动态的更新索引。而索引的更新势必会影响到增删改操作的性能。 构建索引常用的数据结构有哪些? 如散列表、红黑树、跳表、B+ 树,除此之外,位图、布隆过滤器可以作为辅助索引,有序数组可以用来对静态数据构建索引 * 散列表增删改查操作的时间复杂度是 O(1),被一些键值数据库用来构建索引,如 Redis、Memcache。这类索引,一般都构建在内存中。 * 红黑树是常用的平衡二叉查找树,数据插入、删除、查找的时间复杂度是 O(logn),也非常适合用来构建内存索引。Ext 文件系统中,对磁盘块的索引,用的就是红黑树。 * B+ 树比起红黑树更加适合构建存储在磁盘中的索引 (1)B+ 树是一个多叉树,对相同个数的数据构建索引,B+ 树的高度要低于红黑树。 (2)当借助索引查询数据时,读取 B+ 树索引需要的磁盘 IO 次数会更少。 所以,如 MySQL、Oracle等,大部分关系型数据库的索引都是用 B+ 树来实现的 * 跳表也支持快速添加、删除、查找数据,通过调整索引结点个数和数据个数之间的比例,可以很好地平衡索引对内存的消耗及其查询效率。Redis 中的有序集合,就是用跳表来构建的 * 布隆过滤器有一定的判错率,但可以规避它的短处,发挥它的长处 (1)尽管对于判定存在的数据可能并不存在,但是对于判定不存在的数据是一定不存在 (2)布隆过滤器有个大特点:内存占用非常少,所以可以针对数据,构建一个布隆过滤器存储在内存中。 (3)查询数据时,如果布隆过滤器判定数据不存在,就不必读取磁盘中的索引了。对于数据不存在的情况,数据查询就更加快速了。 * 有序数组也可以被作为索引,如果数据是静态的只有查询操作,可以把数据的关键词(查询用的)抽取出来,组织成有序数组,然后利用二分查找算法来快速查找数据。
    2020-02-07
    11
  • 胡小禾
    我以前只是人云亦云地认同“数据结构和算法”十分重要。看完本节,豁然开朗。似乎庞大的计算机体系,将其本质,半隐半现地展示在我面前
    2019-08-02
    9
收起评论
显示
设置
留言
41
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部