压缩列表实际上类似于一个数组,数组中的每一个元素都对应保存一个数据 。和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltAIl 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数;压缩列表在表尾还有一个 zlend,表示列表结束 。
文章插图
在压缩列表中,如果我们要查找定位第一个元素和最后一个元素,可以通过表头三个字段的长度直接定位,复杂度是 O(1) 。而查找其他元素时,就没有这么高效了,只能逐个查找,此时的复杂度就是 O(N) 了 。
我们再来看下跳表 。
有序链表只能逐一查找元素,导致操作起来非常缓慢,于是就出现了跳表 。具体来说,跳表在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位,如下图所示:
文章插图
跳表的快速查找过程
如果我们要在链表中查找 33 这个元素,只能从头开始遍历链表,查找 6 次,直到找到 33 为止 。此时,复杂度是 O(N),查找效率很低 。
为了提高查找速度,我们来增加一级索引:从第一个元素开始,每两个元素选一个出来作为索引 。这些索引再通过指针指向原始的链表 。例如,从前两个元素中抽取元素 1 作为一级索引,从第三、四个元素中抽取元素 11 作为一级索引 。此时,我们只需要 4 次查找就能定位到元素 33 了 。
如果我们还想再快,可以再增加二级索引:从一级索引中,再抽取部分元素作为二级索引 。例如,从一级索引中抽取 1、27、100 作为二级索引,二级索引指向一级索引 。这样,我们只需要 3 次查找,就能定位到元素 33 了 。
可以看到,这个查找过程就是在多级索引上跳来跳去,最后定位到元素 。这也正好符合“跳”表的叫法 。当数据量很大时,跳表的查找复杂度就是 O(logN) 。
好了,我们现在可以按照查找的时间复杂度给这些数据结构分下类了:
文章插图
不同操作的复杂度
集合类型的操作类型很多,有读写单个集合元素的,例如 HGET、HSET , 也有操作多个元素的,例如 SADD,还有对整个集合进行遍历操作的,例如 SMEMBERS 。这么多操作 , 它们的复杂度也各不相同 。而复杂度的高低又是我们选择集合类型的重要依据 。
我总结了一个“四句口诀”,希望能帮助你快速记住集合常见操作的复杂度 。这样你在使用过程中 , 就可以提前规避高复杂度操作了 。
- 单元素操作是基?。?/li>
- 范围操作非常耗时;
- 统计操作通常高效;
第一,单元素操作,是指每一种集合类型对单个数据实现的增删改查操作 。例如,Hash 类型的 HGET、HSET 和 HDEL,Set 类型的 SADD、SREM、SRANDMEMBER 等 。这些操作的复杂度由集合采用的数据结构决定,例如 , HGET、HSET 和 HDEL 是对哈希表做操作,所以它们的复杂度都是 O(1);Set 类型用哈希表作为底层数据结构时 , 它的 SADD、SREM、SRANDMEMBER 复杂度也是 O(1) 。
这里,有个地方你需要注意一下,集合类型支持同时对多个元素进行增删改查,例如 Hash 类型的 HMGET 和 HMSET,Set 类型的 SADD 也支持同时增加多个元素 。此时 , 这些操作的复杂度,就是由单个元素操作复杂度和元素个数决定的 。例如 , HMSET 增加 M 个元素时,复杂度就从 O(1) 变成 O(M) 了 。
第二 , 范围操作,是指集合类型中的遍历操作,可以返回集合中的所有数据,比如 Hash 类型的 HGETALL 和 Set 类型的 SMEMBERS,或者返回一个范围内的部分数据 , 比如 List 类型的 LRANGE 和 ZSet 类型的 ZRANGE 。这类操作的复杂度一般是 O(N),比较耗时,我们应该尽量避免 。
不过,Redis 从 2.8 版本开始提供了 SCAN 系列操作(包括 HSCAN,SSCAN 和 ZSCAN),这类操作实现了渐进式遍历 , 每次只返回有限数量的数据 。这样一来,相比于 HGETALL、SMEMBERS 这类操作来说,就避免了一次性返回所有元素而导致的 Redis 阻塞 。
第三,统计操作,是指集合类型对集合中所有元素个数的记录,例如 LLEN 和 SCARD 。这类操作复杂度只有 O(1),这是因为当集合类型采用压缩列表、双向链表、整数数组这些数据结构时,这些结构中专门记录了元素的个数统计,因此可以高效地完成相关操作 。
推荐阅读
- Nginx配置指南:快速安装与反向代理设置
- 你愿意为“生成式AI”付费吗?
- "白酒圈公认6款性价比超高白酒,你的酒柜里缺了哪几瓶?"
- 六十岁退不了?交社保可以补发吗?你想知道的答案来了!
- 大闸蟹公母有啥区别,哪个更好,你选对了吗?
- 微信分身怎么登录第二个微信?我猜你不清楚这3种微信多开方法
- 想知道手机怎么拍照翻译吗?
- 快速提升记忆力的穴位董氏奇穴 按一个穴位马上记忆力变强
- 难以超越的5部古装探案剧,你若是一部没看,那就太可惜了
- 少年的你经典名句,牧羊少年奇幻之旅经典语录