🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
⭐ Redis⭐
🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
引言
Redis 中的有序集合(Sorted Set,简称 Zset)是一种非常强大且灵活的数据结构。它结合了哈希表和跳跃列表(Skip List)或压缩列表(Ziplist)的优点,能够高效地执行插入、删除以及范围查询操作。与普通集合不同的是,有序集合中的每个元素都有一个分数(score),这个分数用来对集合内的元素进行排序。
有序集合的基本概念
特点
- 唯一性:有序集合中的元素不能重复。
- 可排序性:每个元素都关联着一个浮点类型的分数,基于此分数可以对集合内的元素进行排序。
- 高效操作:支持快速添加/更新元素、获取指定范围的元素等操作。
内部编码
有序集合有两种内部编码方式:
- ziplist(压缩列表):当有序集合的元素个数较少且每个元素较小时使用,以减少内存消耗。
- skiplist(跳跃列表):当元素较多或单个元素较大时使用,以保持操作效率。
现在已经改成 quicklylist 了
基本命令
ZADD
ZADD
命令用于向有序集合中添加新成员或者更新已存在的成员的分数。该命令还支持多个选项,如XX
只更新现有成员,NX
只添加新成员,CH
返回被修改的成员数量,INCR
则类似于ZINCRBY
,增加成员的分数。
语法
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
示例
假设我们有一个名为 myzset
的有序集合:
redis> ZADD myzset 1 "one" # 添加一个成员 "one",分数为 1
(integer) 1
redis> ZADD myzset 2 "two" 3 "three" # 添加两个成员 "two" 和 "three",分数分别为 2 和 3
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES # 按分数升序列出所有成员及其分数
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
ZREM
ZREM
命令从有序集合中移除一个或多个成员。
语法
ZREM key member [member ...]
示例
继续上面的例子,移除成员 "two":
redis> ZREM myzset "two" # 移除成员 "two"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES # 再次查看有序集合
1) "one"
2) "1"
3) "three"
4) "3"
ZRANGE 和 ZREVRANGE
这两个命令分别用于返回按分数升序或降序排列的成员。加上
WITHSCORES
参数可以同时获取成员的分数。
语法
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
示例
redis> ZRANGE myzset 0 -1 WITHSCORES # 按分数升序列出所有成员及其分数
1) "one"
2) "1"
3) "three"
4) "3"
redis> ZREVRANGE myzset 0 -1 WITHSCORES # 按分数降序列出所有成员及其分数
1) "three"
2) "3"
3) "one"
4) "1"
ZCARD
ZCARD
返回有序集合的基数,即集合中的元素数量。
语法
ZCARD key
示例
redis> ZCARD myzset # 获取有序集合中的元素数量
(integer) 2
ZCOUNT
ZCOUNT
返回分数位于给定区间内的成员数量。
语法
ZCOUNT key min max
示例
redis> ZCOUNT myzset 1 3 # 计算分数在 1 到 3 之间的成员数量
(integer) 2
ZINCRBY
ZINCRBY
命令为有序集合中的成员增加给定的增量值,并返回更新后的分数。
语法
ZINCRBY key increment member
示例
redis> ZINCRBY myzset 2 "one" # 将成员 "one" 的分数增加 2
"3"
redis> ZRANGE myzset 0 -1 WITHSCORES # 查看更新后的有序集合
1) "three"
2) "3"
3) "one"
4) "3"
ZINTERSTORE 和 ZUNIONSTORE
ZINTERSTORE
和ZUNIONSTORE
分别用于计算两个或更多有序集合的交集和并集,并将结果存储到一个新的有序集合中。这些命令允许通过权重参数自定义合并逻辑,并支持不同的聚合方式,如SUM
,MIN
, 或MAX
。
语法
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM|MIN|MAX>]
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM|MIN|MAX>]
示例
创建两个有序集合 zset1
和 zset2
,然后计算它们的交集:
redis> ZADD zset1 1 "one" 2 "two" # 创建 zset1
(integer) 2
redis> ZADD zset2 2 "one" 3 "two" 1 "three" # 创建 zset2
(integer) 3
redis> ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 # 计算 zset1 和 zset2 的交集,权重分别为 2 和 3
(integer) 2
redis> ZRANGE out 0 -1 WITHSCORES # 查看交集结果
1) "one"
2) "5"
3) "two"
4) "10"
其他命令
还有一些其他有用的命令,例如:
ZPOPMAX
和ZPOPMIN
用于弹出最大或最小分数的成员。ZREMRANGEBYRANK
和ZREMRANGEBYSCORE
用于移除特定排名或分数范围内的成员。
总结
命令 | 时间复杂度 | 说明 |
---|---|---|
ZADD key score member [score member ...] |
O(k * log(n)) | k 是添加成员的个数,n 是当前有序集合的元素个数 |
ZCARD key |
O(1) | 获取有序集合的基数(元素数量) |
ZSCORE key member |
O(1) | 获取成员的分数 |
ZRANK key member <br> ZREVRANK key member |
O(log(n)) | n 是当前有序集合的元素个数,获取成员的排名 |
ZREM key member [member ...] |
O(k * log(n)) | k 是删除成员的个数,n 是当前有序集合的元素个数 |
ZINCRBY key increment member |
O(log(n)) | n 是当前有序集合的元素个数,增加成员的分数 |
ZRANGE key start end [WITHSCORES] <br> ZREVRANGE key start end [WITHSCORES] |
O(k + log(n)) | k 是获取成员的个数,n 是当前有序集合的元素个数 |
ZRANGEBYSCORE key min max [WITHSCORES] <br> ZREVRANGEBYSCORE key max min [WITHSCORES] |
O(k + log(n)) | k 是获取成员的个数,n 是当前有序集合的元素个数 |
ZCOUNT key min max |
O(log(n)) | n 是当前有序集合的元素个数,计算分数在给定范围内的成员数量 |
ZREMRANGEBYRANK key start end |
O(k + log(n)) | k 是获取成员的个数,n 是当前有序集合的元素个数 |
ZREMRANGEBYSCORE key min max |
O(k + log(n)) | k 是获取成员的个数,n 是当前有序集合的元素个数 |
ZINTERSTORE destination numkeys key [key ...] |
O(n * k) + O(m * log(m)) | n 是输入的集合最小的元素个数,k 是集合个数, m 是目标集合元素个数 |
ZUNIONSTORE destination numkeys key [key ...] |
O(n) + O(m * log(m)) | n 是输入集合总元素个数,m 是目标集合元素个数 |
说明
- k:表示操作涉及的成员个数。
- n:表示当前有序集合的元素个数。
- m:表示目标集合的元素个数。
实际应用场景
排行榜系统
有序集合非常适合实现排行榜功能,比如游戏中的玩家积分榜。每当用户得分发生变化时,可以通过 ZADD
更新用户的分数;而要展示前N名玩家,则可以利用 ZREVRANGE
来获取。
热门商品推荐
在线购物网站可以根据商品的点击量或购买量构建热门商品榜单。使用 ZADD
添加商品信息,ZINCRBY
更新计数,最后通过 ZREVRANGE
获取最受欢迎的商品列表。
社交网络点赞数统计
社交平台上的文章或图片可以获得点赞,我们可以用有序集合记录每篇文章的点赞数。如果需要取消某个点赞,可以用 ZREM
删除对应项。
以上就是关于 Redis 的 zset 有序集合的内柔,后续会更新更多 redis 内容,感谢阅览!!!