亲测可用,若有疑问请私信
在【B+树】:MySQL数据库索引是如何实现的?中,我们讲了MySQL数据库索引的实现原理。MySQL底层依赖的是B+树这种数据结构。那类似Redis这样的Key-Value数据库中的索引,又是怎么实现的呢?底层依赖的有是什么数据结构呢?
今天,我们来讲一下索引这种常用的技术解决思路,底层往往会依赖哪些数据结构。同时,通过索引这个应用场景,我也带你回顾一下,之前我们学过的几种支持动态集合的数据结构。
为什么需要索引?
在实际的软件开发中,业务纷繁复杂。但是万变不离其宗,如果抛开这些业务和功能的外壳,它们的本质都可以抽象为“对数据的存储和计算”。对应到数据结构和算法中,那“存储”需要的就是数据结构,“计算”需要的就是算法。
对于存储的需求,功能上不外乎增删查改。这其实并不复杂,但是一旦存储的数据很多,那性能就成了这些系统要关注的重点,特别是在一些跟存储相关的基础系统(比如MySQL数据库、分布式文件系统等)、中间件(比如消息中间件RocketMQ等)中。
“如何节省存储空间,如何提高数据增删改查的执行效率”,这样的问题就成了设计的重点。而这些系统的实现,都离不开一个东西,那就是索引。索引设计的好坏,直接决定了这些系统是否优秀。
索引这个概念,非常好理解。可以类比书籍的目录来理解。通过目录我们可以快速定位相关知识点的页数,查找的速度也会有质的提高。
索引的需求定义
对于系统设计需求,我们一般可以从功能性需求和非功能性需求两方面来分析。
1.功能性需求
数据是格式化数据还是非格式化数据?要构建索引的原始数据,类型有很多。我把它分为两类,一类是结构化数据,比如MySQL中的数据;另一类是非结构化数据,比如搜索引擎中的网页。对于非结构化数据,我们一般需要做预处理,提取出查询关键词,对关键词构建索引。
数据是静态数据还是动态数据?如果原始数据是一组静态数据,也就是说,不会有数据的增加、删除、更新操作,那么我们在构建索引的时候只需要考虑查询效率就可以了。这样索引的构建就相对简单些。不过大部分情况下我们都是对动态数据构建索引,也就是说,我们不仅要考虑到索引的查询效率,在原始数据更新的同时,我们还需要动态的更新索引。支持动态数据集合的索引,设计起来相对也要更加复杂些。
索引存储在内存还是硬盘?还有种情况是一部分存储在内存,一部分存储在硬盘,这样可以兼顾内存消耗和查询效率。
单值查找还是区间查找?
单关键词查找还是多关键词组合查找?对于单关键词的查找,索引构建起来相对简单些。对于多关键词查询来说,要分多种情况。像MySQL这种结构化数据的查询需求,我们可以实现针对多个关键词的组合,建立索引;对于像搜索引擎这样的非结构数据的查询需求,我们可以针对单个关键词构建索引,然后通过集合操作,比如求并集、求交集等,计算出多个关键词组合的查询结果。
2. 非功能性需求
不管是存储在内存还是磁盘中,索引对存储空间的消耗不能过大。
在考虑索引查询效率的同时,我们还要考虑索引的维护成本。即动态的更新索引的成本。
构建索引的常用数据结构有哪些?
实际上,常用来构建索引的数据结构,就是我们之前讲过的几种支持动态数据集合的数据结构。比如,散列表、红黑树、跳表、B+树。除此之位,位图、布隆过滤器可以作为辅助索引,有序数组可以用来对静态数据构建索引。
散列表增删改查操作的性能非常好,时间复杂度是O(1)。一些键值数据库,比如Redis、Memcache,就是使用散列表来构建索引的。这类索引,一般都构建在内存中。
红黑树作为一种常用的平衡二叉查找树,数据插入、删除、查找的时间复杂度是O(logn),也非常适合用来构建内存索引。Ext文件系统中,对磁盘块的索引,用的就是红黑树。
B+树比起红黑树来说,更加适合构建存储在磁盘中的索引。B+树是一个多叉树,所以对相同个数的数据构建索引,B+树的高度要低于红黑树。当借助索引查询数据的时候,读取B+树索引,需要的磁盘IO次数更少。所以大部分关系型数据库的索引,比如MySQL、Oracle,都是用B+树来实现的。
跳表也支持快速添加、删除、查找数据。而且,我们通过灵活调整索引节点个数和数据个数之间的比例,可以很好的平衡索引对内存的消耗及其查询效率。Redis中的有序集合,就是用跳表来实现的。
除了散列表、红黑树、B+树、跳表之外,位图和布隆过滤器这两个数据结构,也可以用于索引中,辅助存储在磁盘中的索引,加速数据查找的效率。我们看下具体怎么做的:
我们知道,布隆过滤器有一定的判错率。但我们可以规避它的短处,发挥它的长处。尽管对于判定存在的数据,有可能不存在。但对于判定不存在的数据,那肯定就不存在。而且布隆过滤器还有一个更大的特点,就是占用的内存非常少。我们可以针对数据构建一个布隆过滤器,并且存储在内存中。当要查询数据的时候,我们可以先通过布隆过滤器,判定是否存在。如果布隆过滤器判定数据不存在,就没必要读取磁盘中的索引了。对于数据不存在的情况,数据查询更加快速了。
实际上,有序数组也可以被作为索引。如果数据是静态的,也就是不会有插入、删除、更新操作,那我们可以把数据的关键词(查询用的)抽取出来,组织成有序数组,然后利用二分查找算法来快速查找数据。
课后思考
你知道基础系统、中间件、开源软件等系统中,有哪些用到了索引吗?这些系统的索引是如何实现的?
今天的文章如何进行数据查找_查数据的权威网站「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/69700.html