Redis的zset的zrem命令可以做到O(1)吗?

事情是这样的,当我用zrem命令去移除value的时候,我知道他之前会做的几个步骤

  • 1、查找这个value对应的score(通过zset中的dict)
  • 2、根据这个score查找到跳表中的节点
  • 3、删除这个节点

我就想了一下为什么dict为什么要保存score呢?如果保存的是跳表中的节点,那么不就可以做到删除O(1)了吗?理由很简单,链表的删除节点就是O(1)。

带着这个疑问,我百思不得其解,不得不深入一个源码探究一下究竟。我终于找到了真正的答案。

我们先来看看主逻辑

可见,算法复杂度LogN就是在skiplist中删除元素。我们进去看看。

在skiplist中删除元素,大体上,其实就是两步

  • 1、找到所有level上目标节点的"后一个节点"。
  • 2、进行节点删除。

其中#1的算法复杂度就是O(LogN),最大结果是常数32。为什么要#1?

是因为skiplist删除节点时,需要对每层链表都做节点删除操作,这个操作规定了算法复杂度就是O(LogN),因为最差就是每个层级都要判断是否存在这个节点,存在的话需要做删除。

因此,回到问题本身,如果用dict保存节点指针,那么也是需要保存LogN个指针,虽然查找时,可以O(1)拿到所有需要删除的节点,但删除时,算法复杂度也是O(LogN)。存储指针没办法降低算法复杂度反而多了32倍内存!

跳表本身的数据结构规定了必定如此。这个问题本身就不是一个问题。

最后,我们一起看看真正的删除逻辑。

人生总是如此,给自己造一个难题,钻进去后才发现其实那个问题本来就不存在,但不重要了,这个过程反而挺有意思。

相关推荐
霖霖总总5 小时前
[小技巧69]为什么总说MySQL单表“别超 2000 万行”?一篇讲透 InnoDB 存储极限
数据库·mysql
安科士andxe5 小时前
实操指南|安科士1.25G CWDM SFP光模块选型、部署与运维全攻略
运维·数据库·5g
Java爱好狂.6 小时前
RDB&AOF持久化原理解析
java·数据库·redis·后端开发·java编程·java程序员·java八股文
蓝胖子Lcl6 小时前
Mac安装Oracle数据库(M芯片)
数据库·macos·oracle
砚边数影6 小时前
从文档型数据库到企业级数据平台:一次架构演进的思考与实践
数据库·mongodb·架构·kingbase·数据库平替用金仓·金仓数据库
SQL必知必会6 小时前
SQL 删除重复行完全指南
数据库·sql
工业甲酰苯胺6 小时前
spring-事务管理
数据库·sql·spring
全栈前端老曹7 小时前
【Redis】Redis 持久化机制 RDB 与 AOF
前端·javascript·数据库·redis·缓存·node.js·全栈
李慕婉学姐7 小时前
Springboot平安超市商品管理系统6sytj3w6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
Elastic 中国社区官方博客7 小时前
易捷问数(NewmindExAI)平台解决 ES 升级后 AI 助手与 Attack Discovery 不正常问题
大数据·运维·数据库·人工智能·elasticsearch·搜索引擎·ai