数据结构与算法笔记:高级篇 - 索引:如何在海量数据中快速查找某个数据?

概述

在 B+ 树章节,我们讲了 MySQL 数据库索引的实现原理。MySQL 底层依赖 B+ 树这种数据结构。那类似 Redis 这样的 Key-Value 数据库中的索引是怎么实现的呢?底层依赖的又是什么数据结构?

本章,我们就来讲一下索引这种常用的计数解决思路,底层往往会依赖哪些数据结构。同时,通过索引这个应用场景,我也带你回顾一下,之前我们学过的几种支持动态集合的数据结构。


为什么需要索引?

在实际的软件开发中,业务纷繁复杂,功能千变万化,但是万变不离其宗。如果抛开这些业务和功能的外壳,其实他们的本质都可以抽象为 “对数据的的存储和计算”。对应到数据结构和算法中,那 “存储” 需要的就是数据结构,“计算” 需要的就是算法。

对于存储的需求,功能上无外乎增删改查。这其实并不复杂。但是,一旦存储的数据很多,那性能就成了这些系统要关注的重点,特别是在一些跟存储相关的基础系统(比如 MySQL 数据库、分布式文件系统等)、中间件(比如消息中间件 RocketMQ 等)中。

“如何节省存储空间、如何提高数据增删改查的执行效率”,这样的问题就成了设计的重点。而这些系统的实现都离不开一个东西,那就是 索引。不夸张的说,索引设计的好坏,直接决定了这些系统是否优秀。

索引这个概念,非常好理解。你可以类比书籍的目录来理解。如果没有目录,我们想要查找某个知识点的时候,就要一页一页翻。通过目录,我们就可以快速定位相关知识点的页数,查找的速度也会有质的提高。

索引的需求定义

索引的概念不难理解,我想你应该已经搞明白。接下来,我们就分析一下,在设计索引的过程中,需要考虑到的一些因素,换句话说,我们该如何定义清楚需求呢?

对于系统设计需求,我们一般可以从功能性需求非功能性需求两方面来分析。因此,这个问题也不例外。

1.功能性需求

对于功能性需求需要考虑的点,大致可以概括成下面这几点。

数据是格式化数据还是非格式化数据? 要构建索引的原始数据,类型有很多。我把它们分为两类:

  • 一类是格式化数据,比如 MySQL 中的数据;
  • 另一类是非结构化数据,比如搜索引擎中的网页。对于非结构化数据,我们一般需要做预处理,提取出查询关键词,对关键词构建索引。

数据是静态数据还是动态数据?

  • 如果原始数据是一组静态数据,也就是说,不会有数据的增加、删除、更新操作,所以,我们在构建索引的时候,只需要考虑查询效率就可以了。这样,索引的构建就相对简单些。
  • 不过,大部分情况下,我们都是对动态数据构建索引,也就是说,我们不仅要考虑到索引的查询效率,在原始数据更新的同时,我们还需要动态地更新索引。支持动态数据集合的索引,设计起来相对也要更加复杂些。

索引存储在内存还是磁盘?

  • 如果索引存储在内存中,那查询的速度肯定要比存储在磁盘中的高。
  • 但是,如果原始数据量很大的情况下,对应的索引可能也会很大。这个时候,因为内存有限,我们可能就不得不将索引存储在磁盘中了。
  • 实际上,还有第三种情况,那就是一部分存储在内存,一部分存储在磁盘,这样就可以兼顾内存消耗和查询效率。

单值查找还是区间查找?

  • 所谓单值查找,也就是查询关键词等于某个值的数据,这种查询需求最常见。
  • 所谓区间查找,就是查找关键词处于某个区间值的所有数据。

你可以类比 MySQL 数据库的查询需求,自己想象一下。实际上不同的应用场景,查询的需求会多种多样。

单关键词查找还是多关键词查找? 比如,搜索索引中构建的索引,既要支持一个关键词的查找(比如 “数据结构”),也要支持组合关键词查找(比如 “数据结构 AND 算法”)。

  • 对于但关键词的查找,索引构建起来相对简单些。
  • 对于多关键词查询来说,要分多钟情况。
    • 向 MySQL 这种结构化数据的查询需求,我们可以针对多个关键词的组合,建立索引;
    • 对于像搜索引擎这样的非结构数据的查询需求,我们可以针对单个关键词构建索引,然后通过集合操作,求并集、求交集,计算出多个关键词组合的查询结果。

实际上,不同的场景,不同的原始数据,对于索引的需求也会千差万别。这里只是列举了一些比较有共性的需求。

2.非功能性需求

讲完了功能性需求,再来看下,索引设计的非功能性需求。

不管是存储在内存中还是磁盘中,索引对存储空间的消耗不能过大

  • 如果存储在内存中,索引对占用存储空间的限制就会非常苛刻。比较内存空间非常有限,一个中间件启动后就占用几个 GB 的内存,开发者显然是无法接受的。
  • 如果存储在磁盘中,那索引对占用存储空间的限制,稍微会放宽一些。但是,我们也不能掉以轻心。因为,有时候,索引对存储空间的消耗会超狗原始数据。

在考虑索引查询效率的同时,我们还要考虑索引的维护成本。索引的目的是提高查询的效率。但是,基于动态数据集合构建的索引,我们还要考虑到,索引的维护成本。因为在原始数据动态增删改查的同时,我们也要动态地更新索引。而索引的更新势必会影响到增删改操作的性能。

构建索引常用的数据结构有哪些?

刚刚从很宏观的监督,总结了在索引设计的过程中,需要考虑的一些共性因素。现在,我们就来看下,对于不同需求的索引结构,底层一般是使用哪种数据结构的。

实际上,常用来构建索引的数据结构,就是我们之前讲过的几种支持动态数据集合的数据结构。比如,散列表、红黑树、跳表、B+ 树。此外,位图、布隆过滤可以作为辅助索引,有序数组可以用来对静态数据构建索引。

我们知道,散列表的增删改查操作的性能非常好,时间复杂度是 O(1)。一些键值数据库,比如 Redis、Memcache,就是使用散列表来构建索引的。这类索引,一般都构建在内存中。

红黑树作为一种常用的平衡二叉查找树,数据插入、删除、查找时间复杂度都是 O ( l o g n ) O(logn) O(logn),也非常适合用来构建索引。Ext 索引文件系统中,对磁盘块的索引,用的就是红黑树。

B+ 树比如红黑树来说,更加适合构建存储在磁盘中的索引。B+ 树是一个多叉树,所以,对相同个数的数据构建索引,B+ 树的高度要低于红黑树。当借助索引查询数据的时候,读取 B+ 树的索引,需要的磁盘 IO 次数会更少。所以,大部分关系型数据库的索引,比如 MySQL、Oracle,都是用 B+ 树来实现的。

跳表也支持快速添加、删除、查找数据。而且,我们通过灵活调整索引结点个数和数据个数之间的比例,可以很大地平衡索引对内存的消耗及其查询效率。 Redis 中的有序集合,就是用跳表来实现的。

除了,散列表、红黑树、B+ 树、跳表之外,位图和布隆过滤器这两个数据结构,也可以用于索引中,辅助存储在磁盘中的索引,加速数据查找的效率。我们来看下,具体是怎么做的?

我们知道,布隆过滤器有一定的判错率。但是,我们可以规避它的短处,发挥它的长处。尽管对于判定存在的数据,有可能并不存在,但是对于判定不存在的数据,那肯定就是不存在的。而且,布隆过滤器还有一个更大的特点,那就是内存占用非常少。我们可以针对数据,构建一个布隆过滤器,并且存储在内存中。当要查询数据的时候,我们可以先通过布隆过滤器,判定是否存在。如果通过布隆过滤器判定数据不存在,那我们就没有必要读取磁盘中的索引了。对于数据不存在的情况,数据查询就更加快速了。

实际上,有序数组也可以被作为索引。如果数据是静态的,也就是不会插入、删除、更新操作,那我们可以把数据的关键词(查询用的)抽取出来,组织成有序数组,然后利用二分查找算法快速查找数据。

总结

本章是一个总结课。从索引这个非常常用的技术方案,给你展示了散列表、红黑树、跳表、B+ 树、位图、布隆过滤器、有序数组这些数据结构的应用场景。学习完这篇文章后,不知道你对数据结构以及索引,有没有更加清晰的认识呢?

从本章的内容中,你应该可以看出,架构设计离不开数据结构和算法。要向成长为一名优秀的架构师、基础架构师,数据结构和算法的根基一定要打稳。因为,哪些看似很惊艳的架构设计思路,实际上,都是来自最常用的数据结构和算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/36128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仓颉开发入门初体验

作者:黄林晴 顺便吆喝一声,如果你计算机、软件工程、电子等相关专业本科及以上学历,欢迎来共事。前端/后端/测试均可投,技术大厂。 前言 在刚刚召开的华为开发者大会(HDC 2024)上,华为内部研…

如何在Java中使用Levenshtein距离实现字符串相似度匹配

在许多应用中,我们需要根据用户输入的问题找到最匹配的已知问题。Levenshtein距离(编辑距离)是一个强大的工具,可以帮助我们衡量两个字符串之间的差异,并进一步计算它们的相似度。本文将使用一个具体的例子来展示如何在…

从架构设计的角度分析ios自带网络库和AFNetworking

总结(先说明文章分析出的一些‘认知’) 从本文中,我们可以总结出一些框架设计上的“认知”: 对于通用的常规配置信息方面的设计,我们可以通过定义一个“类似于NSURLSessionConfiguration、NSURLRequest”的类来完成设…

【算法专题--栈】后缀表达式求值 -- 高频面试题(图文详解,小白一看就会!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐解题思路 ⭐案例图解 四、总结与提炼 五、共勉 一、前言 后缀表达式求值 这道题,可以说是--栈专题--,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中&…

什么是ArchiMate?有优缺点和运用场景?

一、什么是ArchiMate? ArchiMate是一种由The Open Group发布的企业级标准,它是一种整合多种架构的可视化业务分析模型语言,也属于架构描述语言(ADL)。ArchiMate主要从业务、应用和技术三个层次(Layer)&…

QT在visual studio环境打开控制台窗口

明确需求 在VS环境中开发QT应用,有时遇到BUG想看日志,但是默认VS环境没有显示控制台窗口可看日志。 解决方法 对工程名单击右键。 点击属性,在打开界面按照如下图操作。 设置完成后弹出的控制台窗口如下图。

[Cloud Networking] VLAN

1 为什么需要 VLAN(Virtual Local Area Network) VLAN是一个逻辑网络,VLAN将设备/用户进行逻辑分组,VLAN需要在Switch上创建。为什么需要这样呢?为何不能所有设备都在同一个网络? 如下网络,如果设备过多,…

【日记】怎么上了一天班饭都没得吃(659 字)

正文 今天算是混得最惨的一天了。 下午开始,柜面主管出差,她找了个代班,好家伙,代班直接不下来,于是整个营业室就只有我一个人了。所有客户逮着我一个人薅。我才下来一个月啊…… 明天她还不回来,要下周一&…

【UE5.3】笔记6-第一个简单小游戏

打砖块小游戏: 1、制造一面砖块组成的墙 在关卡中放置一个cube,放这地面上,将其转换成蓝图类,改名BP_Cube,更换砖块的贴图,按住alt键进行拷贝,堆出一面墙,复制出来的会很多,全选移动…

报餐小程序可以运用在饭堂的哪方面

随着科技的快速发展,智能化、信息化的管理方式逐渐渗透到我们日常生活的方方面面。在饭堂管理中,报餐小程序的应用为传统的餐饮管理方式带来了革命性的变革。本文将探讨报餐小程序在饭堂管理中的应用及其带来的优势。 一、报餐小程序的基本功能 报餐小程…

数据资产管理的艺术:构建智能化、精细化的数据资产管理体系,从数据整合、分析到决策支持,为企业提供一站式的数据资产解决方案,助力企业把握数字时代的新机遇

一、引言 在数字化浪潮席卷全球的今天,数据已经成为企业最重要的资产之一。如何高效、安全地管理这些海量数据,从中提取有价值的信息,并将其转化为决策支持,是每个企业都必须面对的挑战。本文将探讨数据资产管理的艺术&#xff0…

新风口不再是直播,云微客带你领略短视频矩阵的魅力

只要你细心观察,就能发现很多品牌都在做短视频矩阵,正是凭借大量的短视频矩阵账号带来的流量曝光,这些品牌才能覆盖数以万计的客户人群,才能每天不断地产生新订单。 有很多人觉得矩阵不就是多注册账号吗?其实短视频矩阵…

mysql 查找表中重复数据 类型题目

只要后续 有查找重复数据的题目 都可以 借鉴 给你 一个表 里面 只有 id 字段,和一个 num字段 查找 num 字段中 相同数值 出现的次数大于等于2的 数值 1. 我们 首先可以想到 分表 把这一张表分成两张表 查询 两张表的num 值相同的 且 id 不同的,但是…

循环冗余校验

循环冗余校验(Cyclic Redundancy Check,简称CRC)是一种广泛使用的错误检测编码技术,用于检测数据在传输或存储过程中是否发生错误。CRC通过在数据后面添加一个校验值(通常称为CRC码或CRC校验和)来实现错误检…

代理IP对SEO影响分析:提升网站排名的关键策略

你是否曾经为网站排名难以提升而苦恼?代理服务器或许就是你忽略的关键因素。在竞争激烈的互联网环境中,了解代理服务器对SEO的影响,有助于你采取更有效的策略,提高网站的搜索引擎排名。本文将为你详细分析代理服务器在SEO优化中的…

node项目-使用http模块发送get-post请求

前言 http模块是node.js提供内置模块,可以用来发送请求使用场景是本身这个node服务就是后端,调用第三方api或者其他服务使用http模块http模块和axios本质上是一个东西,看自己怎么选择使用 代码实现-不能直接复制-看注释 1.请求文件代码 /…

EtherCAT主站IGH-- 2 -- IGH之coe_emerg_ring.h/c文件解析

EtherCAT主站IGH-- 2 -- IGH之coe_emerg_ring.h/c文件解析 0 预览一 该文件功能coe_emerg_ring.c 文件功能函数预览 二 函数功能介绍coe_emerg_ring.c 中主要函数的作用1. ec_coe_emerg_ring_init2. ec_coe_emerg_ring_clear3. ec_coe_emerg_ring_size4. ec_coe_emerg_ring_pus…

聊聊啥项目适合做自动化测试

作为测试从业者,你是否遇到过这样的场景,某天公司大Boss找你谈话。 老板:小李,最近工作辛苦了 小李:常感谢您的认可,这不仅是对我个人的鼓励,更是对我们整个团队努力的认可。我们的成果离不开每…

Linux libreoffice安装 word转pdf 中文乱码(缺少字体解决)

libreoffice 的安装 yum install -y libreoffice版本验证 libreoffice --version参考文章 word转pdf 命令 转换命令 要将Word文档(.doc或.docx)转换为PDF格式,可以使用以下命令: libreoffice --headless --convert-to pdf your_word_document.docx指…

计算机视觉——OpenCV C++实现凸包

概述 在图像中发现和分析形式是解决大多数计算机视觉问题的技巧之一,获取轮廓是其中之一。对于新手来说,我会将轮廓描述为“仅仅是一条连接所有位于形状边缘上的点的曲线。” 假设我有下面这张手的图像,手的轮廓由绿线表示。红点代表我们将…