Redis跳表

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis跳表


简介

Redis 中的有序集合(Sorted Set)是用跳表(Skip list)来实现的。这里就需要了解一下跳表的概念。

链表:链表插入,删除某一个节点的时间复杂度是O(1),但是查询的时间复杂度是O(n)。

跳表就是解决链表在有序节点场景下的查询时间复杂度高问题。时间复杂度能达到O(logn)。

跳表

跳表是有多个层级的链表组成。如下图的多级索引和原始链表,每层索引都是一条链表。

跳表每一层的链表都会随机包含一些原始链表的节点(通过跳表的动态更新策略实现)。层数越高,链表节点越少。

查询策略

因此查询节点时,从最高层级向下查找,通过高层级索引节点的大小和待查找值大小比较,就能比较出查找值大小是在哪两个节点之间,或者就等于某个节点。再一步一步往低层级索引的链表上查找,最终总能找到相等的那个节点。

可以看出,跳表其实是一种空间换时间的策略来减少查询的时间复杂度。

动态更新策略

插入节点

  1. 在跳表中插入新元素时,需要先在底层链表中插入该元素,然后决定该元素是否要成为索引节点。
  2. 可以使用随机函数来决定该元素是否需要成为下一层的索引节点,如果需要,则在下一层都插入一个新的索引节点,该索引节点指向上一层中同一位置的元素。

删除节点

  1. 在跳表中删除元素时,需要先在底层链表中删除该元素,然后考虑是否需要删除对应的索引节点。
  2. 可以从顶层开始遍历跳表,如果某个索引节点指向的元素已经不存在了,则需要删除该索引节点,同时将上一层中相同位置的索引节点指向下一层中相同位置的元素。
  3. 如果最上层的索引节点被删除了,则需要将跳表的高度减少一层。

跳表的高度控制策略

跳表的高度控制策略通常是基于概率的可以定义一个概率p,每次插入元素时,以概率p(0<p<1)决定是否将该元素作为索引节点。查询时间复杂度就是log1/p(n)。

如果是以1/2概率决定是否添加链表,则跳表的高度最大为log2(n)。查询效率也就是log2(n)。

概率过大 vs 概率过小

概率过大,过小都不好。

概率过大会导致跳表中索引节点的数量增加,从而增加了查询时需要访问的节点数,降低了查询效率。因为跳表的查询效率取决于索引节点的数量,节点数量越多,查询效率就越低。

概率越小并不一定就越好。因为概率越小,索引节点的数量就会减少,从而节省了空间,但是查询效率也会降低。如果概率过小,跳表的高度可能无法达到预期的水平,从而失去了跳表的优势。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
6月前
|
NoSQL 算法 分布式数据库
【Redis】求求你,别再问跳表了
【Redis】求求你,别再问跳表了
|
6天前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
6月前
|
NoSQL 算法 Redis
redis7.0源码阅读(五):跳表(skiplist)
redis7.0源码阅读(五):跳表(skiplist)
207 1
|
6月前
|
NoSQL Go API
Golang实现redis系列-(4)实现跳表容器
Golang实现redis系列-(4)实现跳表容器
36 0
|
6月前
|
存储 NoSQL Redis
Redis数据结构之——跳表skiplist
Redis数据结构之——跳表skiplist
|
12月前
|
存储 NoSQL Redis
Redis 跳表skiplist
Redis 跳表skiplist
|
12月前
|
存储 NoSQL 算法
redis6.0源码分析:跳表skiplist
redis6.0源码分析:跳表skiplist
59 0
|
存储 NoSQL Redis
Redis从入门到精通之底层数据结构跳表 SkipList
跳表(Skip List)是一种基于链表的数据结构,用于快速地插入、删除和查找元素。跳表通过多层级的指针数组来实现快速的操作,时间复杂度为O(log n),其中n为跳表中元素的个数。Redis中的有序集合(Sorted Set)就是通过跳表来实现的。
831 7
Redis从入门到精通之底层数据结构跳表 SkipList
|
存储 NoSQL Redis
零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)
>之前就说了要来西索Redis,现在来辣! >本文的部分内容参考自《小林Coding》,部分地方根据源代码进行剖析。 >Redis源码地址:https://github.com/redis/redis.git
134 0
零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)
|
存储 NoSQL 安全
Redis源码之跳表数据结构
Redis源码之跳表数据结构