关于redis数据类型操作的应用场景及时间复杂度

String类型命令时间复杂度和应用场景

  • set key value 时间复杂度: O(1)

  • SETNX key value 时间复杂度: O(1)

SetNX用来实现分布式锁

  • SETEX key seconds value 时间复杂度: O(1)
  • PSETEX key milliseconds value 时间复杂度: O(1)
  • GET key 时间复杂度: O(1)
  • GETSET key value 时间复杂度: O(1)
  • STRLEN key 时间复杂度: O(1)
  • APPEND key value 平摊O(1)
  • SETRANGE key offset value 时间复杂度:对于长度较短的字符串,命令的平摊复杂度O(1);对于长度较大的字符串,命令的复杂度为 O(M) ,其中 M 为 value 的长度。
  • GETRANGE key start end 时间复杂度: O(N),其中 N 为被返回的字符串的长度。
  • INCR key 时间复杂度: O(1)

INCR 系列的命令可以用来实现计数器的功能

  • INCRBY key increment 时间复杂度: O(1)
  • INCRBYFLOAT key increment 时间复杂度: O(1)
  • DECR key 时间复杂度: O(1)
  • MSET key value [key value …] 时间复杂度: O(N),其中 N 为被设置的键数量。
  • MSETNX key value [key value …] 时间复杂度: O(N), 其中 N 为被设置的键数量。
  • MGET key [key …] 时间复杂度: O(N) ,其中 N 为给定键的数量。

string类型高时间复杂度的命令汇总

m系列的命令 和 getrange 命令 以及一定情况下的setrange 命令

List类型的命令的时间复杂度和应用场景

  • LPUSH key value [value …] 时间复杂度: O(1)
  • LPUSHX key value 时间复杂度: O(1)
  • RPUSH key value [value …] 时间复杂度: O(1)
  • RPUSHX key value 时间复杂度: O(1)
  • LPOP key 时间复杂度: O(1)
  • RPOP key 时间复杂度: O(1)
  • RPOPLPUSH source destination 时间复杂度: O(1)
  • LREM key count value 时间复杂度: O(N)
  • LLEN key 时间复杂度: O(1)
  • LINDEX key index 时间复杂度: O(N)
  • LINSERT key BEFORE|AFTER pivot value 时间复杂度: O(N), N 为寻找 pivot 过程中经过的元素数量。
  • LSET key index value 时间复杂度:对头元素或尾元素进行 LSET 操作,复杂度为 O(1)。其他情况下,为 O(N), N 为列表的长度。
  • LRANGE key start stop 时间复杂度: O(S+N), S 为偏移量 start , N 为指定区间内元素的数量。
  • LTRIM key start stop 时间复杂度为 O(N) ,N为删除的元素

LTRIM 命令通常和 LPUSH key value [value …] 命令或 RPUSH key value [value …] 命令配合使用,举个例子:LPUSH log newest_log
LTRIM log 0 99
这个例子模拟了一个日志程序,每次将最新日志 newest_log 放到 log 列表中,并且只保留最新的 100 项。注意当这样使用 LTRIM 命令时,时间复杂度是O(1),因为平均情况下,每次只有一个元素被移除。

  • BLPOP key [key …] timeout 时间复杂度: O(1)
    阻塞队列

有时候,为了等待一个新元素到达数据中,需要使用轮询的方式对数据进行探查。
另一种更好的方式是,使用系统提供的阻塞原语,在新元素到达时立即进行处理,而新元素还没到达时,就一直阻塞住,避免轮询占用资源。
对于 Redis ,我们似乎需要一个阻塞版的 SPOP key 命令,但实际上,使用 BLPOP 或者 BRPOP key [key …] timeout 就能很好地解决这个问题。

  • BRPOPLPUSH source destination timeout 时间复杂度: O(1)
    安全队列

Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个客户端通过 LPUSH key value [value …] 命令将消息放入队列中,而另一个客户端通过 RPOP key 或者 BRPOP key [key …] timeout 命令取出队列中等待时间最长的消息。不幸的是,上面的队列方法是『不安全』的,因为在这个过程中,一个客户端可能在取出一个消息之后崩溃,而未处理完的消息也就因此丢失。使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH source destination timeout )可以解决这个问题:因为它不仅返回一个消息,同时还将这个消息添加到另一个备份列表当中,如果一切正常的话,当一个客户端完成某个消息的处理之后,可以用 LREM key count value 命令将这个消息从备份表删除。最后,还可以添加一个客户端专门用于监视备份表,它自动地将超过一定处理时限的消息重新放入队列中去(负责处理该消息的客户端可能已经崩溃),这样就不会丢失任何消息了。

循环队列

通过使用相同的 key 作为 RPOPLPUSH 命令的两个参数,客户端可以用一个接一个地获取列表元素的方式,取得列表的所有元素,而不必像 LRANGE key start stop 命令那样一下子将所有列表元素都从服务器传送到客户端中(两种方式的总复杂度都是 O(N))。
以上的模式甚至在以下的两个情况下也能正常工作:有多个客户端同时对同一个列表进行旋转(rotating),它们获取不同的元素,直到所有元素都被读取完,之后又从头开始。
有客户端在向列表尾部(右边)添加新元素。这个模式使得我们可以很容易实现这样一类系统:有 N 个客户端,需要连续不断地对一些元素进行处理,而且处理的过程必须尽可能地快。一个典型的例子就是服务器的监控程序:它们需要在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性。
这个模式使得我们可以很容易实现这样一类系统:有 N 个客户端,需要连续不断地对一些元素进行处理,而且处理的过程必须尽可能地快。一个典型的例子就是服务器的监控程序:它们需要在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性。注意,使用这个模式的客户端是易于扩展(scala)且安全(reliable)的,因为就算接收到元素的客户端失败,元素还是保存在列表里面,不会丢失,等到下个迭代来临的时候,别的客户端又可以继续处理这些元素了。

列表数据类型命令时间复杂度高的命令

LREM key count value 时间复杂度: O(N)  
LTRIM key start stop  时间复杂度为 O(N) ,N为删除的元素
LSET 操作,复杂度为 O(1)。其他情况下,为 O(N), N 为列表的长度。
LRANGE key start stop  时间复杂度: O(S+N), S 为偏移量 start , N 为指定区间内元素的数量。
LINDEX key index   时间复杂度: O(N) 

SET类型的基本命令时间复杂度及应用场景

  • SADD key member [member …] 时间复杂度: O(N), N 是被添加的元素的数量。
  • SISMEMBER key member 时间复杂度: O(1)
  • SPOP key 时间复杂度: O(1)
  • SRANDMEMBER key [count] 时间复杂度: 只提供 key 参数时为 O(1) 。如果提供了 count 参数,那么为 O(N) ,N 为返回数组的元素个数。
  • SREM key member [member …] 时间复杂度: O(N), N 为给定 member 元素的数量。
  • SMOVE source destination member 时间复杂度: O(1)
  • SCARD key 时间复杂度: O(1)
  • SMEMBERS key 时间复杂度: O(N), N 为集合的基数。
  • SINTER key [key …] 时间复杂度: O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。

实现关注模型,可能认识的人

  • SINTERSTORE destination key [key …] 时间复杂度: O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。
  • SUNION key [key …] 时间复杂度: O(N), N 是所有给定集合的成员数量之和。
  • SUNIONSTORE destination key [key …] 时间复杂度: O(N), N 是所有给定集合的成员数量之和。
  • SDIFF key [key …] 时间复杂度: O(N), N 是所有给定集合的成员数量之和。

ZSET类型的命令的时间复杂度及应用场景

redis的zset天生是用来做排行榜的、好友列表, 去重, 历史记录等业务需求。

  • ZADD key score member [[score member] [score member] …] 时间复杂度: O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。
  • ZSCORE key member 时间复杂度: O(1)
  • ZINCRBY key increment member 时间复杂度: O(log(N))
  • ZCOUNT key min max 时间复杂度: O(log(N)), N 为有序集的基数。
  • ZRANGE key start stop [WITHSCORES] 时间复杂度: O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。
  • ZREVRANGE key start stop [WITHSCORES] 时间复杂度: O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 时间复杂度: O(log(N)+M), N 为有序集的基数, M 为被结果集的基数。
  • ZRANK key member 时间复杂度: O(log(N))
  • ZREVRANK key member 时间复杂度: O(log(N))
  • ZREM key member [member …] 时间复杂度: O(M*log(N)), N 为有序集的基数, M 为被成功移除的成员的数量。
  • ZREMRANGEBYRANK key start stop 时间复杂度: O(log(N)+M), N 为有序集的基数,而 M 为被移除成员的数量。
  • ZREMRANGEBYSCORE key min max 时间复杂度: O(log(N)+M), N 为有序集的基数,而 M 为被移除成员的数量。
  • ZRANGEBYLEX key min max [LIMIT offset count] 时间复杂度:O(log(N)+M), 其中 N 为有序集合的元素数量, 而 M 则是命令返回的元素数量 命令会使用 C 语言的 memcmp() 函数, 对集合中的每个成员进行逐个字节的对比(byte-by-byte compare), 并按照从低到高的顺序, 返回排序后的集合成员。 如果两个字符串有一部分内容是相同的话, 那么命令会认为较长的字符串比较短的字符串要大
  • ZLEXCOUNT key min max 时间复杂度: O(log(N)),其中 N 为有序集合包含的元素数量。
  • ZREMRANGEBYLEX key min max 时间复杂度: O(log(N)+M), 其中 N 为有序集合的元素数量, 而 M 则为被移除的元素数量。

HASH类型命令及其时间复杂度

  • HSET hash field value 时间复杂度: O(1)
  • HSETNX hash field value 时间复杂度: O(1)
  • HGET hash field 时间复杂度: O(1)
  • HEXISTS hash field 时间复杂度: O(1)
  • HDEL key field [field …] 时间复杂度:O(N), N 为要删除的域的数量。
  • HLEN key 时间复杂度:O(1)
  • HSTRLEN key field 时间复杂度:O(1)
  • HINCRBY key field increment 时间复杂度:O(1)
  • HMSET key field value [field value …] 时间复杂度:O(N),N 为 field-value 对的数量。
  • HMGET key field [field …] 时间复杂度:O(N), N 为给定域的数量。
  • HKEYS key 时间复杂度:O(N), N 为哈希表的大小。
  • HVALS key 时间复杂度:O(N)
  • HGETALL key 时间复杂度:O(N)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis数据类型有String、Hash、List、Set、Zset、GEO、Stream、HyperLogLog和Bitmap。在实际应用中,不同的数据类型可以用于不同的场景。 1. String类型:主要用于缓存和存储单个的值,比如用户的登录信息、计数器等。 2. Hash类型:适用于存储和获取对象的多个字段,比如存储用户的信息、商品的属性等。 3. List类型:可以按照插入顺序存储多个值,并支持在列表的两端进行插入和删除操作,比如消息队列、实时聊天记录等。 4. Set类型:用于存储多个不重复的值,也可以进行交集、并集、差集等操作,比如存储用户的好友列表、标签等。 5. Zset类型:有序集合,每个元素都会关联一个分数,可以根据分数进行范围查找和排序,适用于排行榜、带权重的数据等。 6. GEO类型:用于地理位置信息的存储和查询,可以计算距离、查找附近的位置等。 7. Stream类型:适用于消息队列的场景,可以按照时间顺序存储和消费消息。 8. HyperLogLog类型:用于统计独立元素的个数,可以进行基数估算,适用于统计UV、PV等场景。 9. Bitmap类型:用于位图操作,可以进行位运算和统计,比如用户签到、在线状态等。 在实际应用中,根据具体的需求和数据特点,选择合适的Redis数据类型可以带来更好的性能和扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [最全总结Redis数据类型使用场景](https://blog.csdn.net/qq_27681741/article/details/125289210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值