title: 有序集合zset
categories:
- C++ Backend
- Redis
- Redis command
- Data structure
tags:
- Redis
date: 2025-04-03 00:00:00
cover: /images/Redis.png

zset

概述

zset是有序集合。zset中的member中同时引入了一个属性,分数,浮点类型。每个member都会安排一个分数,进行排序的时候,就是按照此处的分数大小来进行升序降序排序。

alt text

普通命令

ZADD

功能:向有序集合中已经有的元素个数
时间复杂度:$O(logN)$

ZADD key [NX | XX] [GT | LT] [INCR] socore number [score member...]

127.0.0.1:6379> zadd key 99 张三 98 李四 97 王五 96 赵六
(integer) 4
127.0.0.1:6379> zrange key 0 -1
1) "\xe8\xb5\xb5\xe5\x85\xad"
2) "\xe7\x8e\x8b\xe4\xba\x94"
3) "\xe6\x9d\x8e\xe5\x9b\x9b"
4) "\xe5\xbc\xa0\xe4\xb8\x89"

127.0.0.1:6379> zadd key 97 赵六
0
127.0.0.1:6379> zrange key 0 -1 withscores
王五 97
赵六 97
李四 98
张三 99

127.0.0.1:6379> zadd key NX 97 六
1
127.0.0.1:6379> zrange key 0 -1 withscores
六 97 
王五 97 
赵六 97
李四 98
张三 99
127.0.0.1:6379> zadd key NX 99 六
0
127.0.0.1:6379> zrange key 0 -1 withscores
六 97
王五 97
赵六 97
李四 98
张三 99

127.0.0.1:6379> zadd key XX 99 六
0
127.0.0.1:6379> zrange key 0 -1 withscores
王五 97
赵六 97
李四 98
六 99
张三 99

127.0.0.1:6379> zadd key incr 10 六
109
127.0.0.1:6379> zrange key 0 -1 withscores
王五 97
赵六 97
李四 98
张三 99
六 109

memberscore称为是一个pair。对于有序集合来说,我们可以根据member找到score,也可以根据score找到member

ZRANGE

功能:查询有序集合中[start,stop]的元素。
时间复杂度:$O(logN + M)$,M是start到stop之间的元素个数
返回值:区间内元素的列表

ZRANGE key start stop [withscores]

user@DESKTOP-KFNQORU:~$ redis-cli --raw
127.0.0.1:6379> zrange key 0 -1
赵六 王五 李四 张三
127.0.0.1:6379> zrange key 0 -1 withscores
赵六 96
王五 97
李四 98
张三 99

ZCARD

功能:获取一个zset的基数,即zset中的元素个数
时间复杂度:$O(1)$

ZCARD key

ZCOUNT

功能:返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过()排除。
时间复杂度:$O(logN)$
返回值:满足条件的元素列表个数

ZCOUNT key min max

127.0.0.1:6379> zrange key 0 -1 withscores
1) "3"
2) "94"
3) "1"
4) "95"
5) "2"
6) "96"
7) "4"
8) "97"
127.0.0.1:6379> zcount key (95 (97
(integer) 1
127.0.0.1:6379> zcount key 95 97
(integer) 3

ZREVRANGE

功能:逆序遍历打印zset。
时间复杂度:$O(logN + M)$,M是start到stop之间的元素个数
返回值:区间内元素的列表

127.0.0.1:6379> zrange key 0 -1 withscores
1) "3"
2) "94"
3) "1"
4) "95"
5) "2"
6) "96"
7) "4"
8) "97"
127.0.0.1:6379> zcount key (95 (97
(integer) 1
127.0.0.1:6379> zrevrange key 0 -1 withscores
1) "4"
2) "97"
3) "2"
4) "96"
5) "1"
6) "95"
7) "3"
8) "94"

ZRANGEBYSCORE

功能:按照分数来找元素的,和ZCOUNT相似。
时间复杂度:$O(logN + M)$,M是start到stop之间的元素个数
返回值:区间内元素的列表
注意:这个功能在之后的redis版本会废弃,功能合并到ZRANGE中。

ZRANGEBYSCORE key min max [WITHSCORES]

127.0.0.1:6379> ZRANGEBYSCORE key 94 97
1) "3"
2) "1"
3) "2"
4) "4"
127.0.0.1:6379> ZRANGEBYSCORE key 94 97 WITHSCORES
1) "3"
2) "94"
3) "1"
4) "95"
5) "2"
6) "96"
7) "4"
8) "97"

有序集合的删除指令

ZPOPMAX

功能:删除并返回分数最高的count个元素。如果存在多个元素,分数相同,同时为最大值,zpopmax删的时候,仍然只删除其中一个元素。
时间复杂度:$O(logN * M)$ M是被删除元素的个数,N有序集合中的元素个数。
返回值:分数和元素列表。

ZPOPMAX key [count]

127.0.0.1:6379> zpopmax key
张三 99
127.0.0.1:6379> zrange key 0 -1 withscores
赵六 96
王五 97
李四 98
127.0.0.1:6379> zpopmax key 2
李四 98
王五 97
127.0.0.1:6379> zrange key 0 -1 withscores
赵六 96
127.0.0.1:6379> zpopmax key
筑起 99
127.0.0.1:6379> zrange key 0 -1 withscores
赵六 96
王五 97
李四 98
张三 99

BZPOPMAX

功能:类似于一个阻塞版的优先级队列,每个key都是一个有序集合,阻塞也是在有序集合为空的时候触发阻塞,阻塞到有其他客户端插入元素。timeout表示超时时间,表示超时多久。如果有序集合里面已经有元素了,那么直接返回,不会再阻塞了。
时间复杂度:$O(logN)$,在若干个key中只删除一次。

BZPOPMAX key [key...] timeout

127.0.0.1:6379> zadd key 10 张三
1
127.0.0.1:6379> BZPOPMAX key 600
key
张三
10

ZPOPMIN

功能:删除集合中最小的元素。
时间复杂度:$O(logN)$

ZPOPMIN key [count]

127.0.0.1:6379> zadd key 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> zpopmin key 
zhangsan
10

BZPOPMIN

功能:删除集合中最小的元素。timeout表示超时时间,表示超时多久。如果有序集合里面已经有元素了,那么直接返回,不会再阻塞了。

BZPOPMIN key [key...] timeout

127.0.0.1:6379> zadd key 10 张三
1
127.0.0.1:6379> BZPOPMIN key 600
key
张三
10

ZRANK

返回:获取member的下标,正着算
时间复杂度:$O(logN)$

ZRANK key member

127.0.0.1:6379> zadd key 10 zhangsan 20 lisi 30 wangwu 40 zhaouliu
4
127.0.0.1:6379> zrank key lisi
1
127.0.0.1:6379> zrank key li
(nil)

ZREVRANK

返回:获取member的下标,反着算
时间复杂度:$O(logN)$

ZREVRANK key member

127.0.0.1:6379> zadd key 10 zhangsan 20 lisi 30 wangwu 40 zhaouliu
4
127.0.0.1:6379> zrevrank key lisi
2
127.0.0.1:6379> zrevrank key li
(nil)

ZSCORE

功能:返回查询元素的分数
时间复杂度:O(1)

127.0.0.1:6379> zscore key lisi
20

ZREM

功能:删除指定元素
时间复杂度:$O(logN * M)$。N是集合中的元素个数,M是member参数个数。
返回值:本次删除元素的个数

ZREM key member [member...]

127.0.0.1:6379> zrem key lisi
1

ZREMRANGBYRANK

功能:根据有序集合中的先后顺序范围删除
时间复杂度:$O(logN + M)$,N是整个有序集合的元素个数,M是start-stop区间中元素个数
返回值:本次删除元素的个数

zremrangebyrank key start stop

127.0.0.1:6379> zremrangebyrank key 1 2
2

ZREMRANGBYSCORE

功能:根据有序集合的分数范围进行删除。闭区间删除。
时间复杂度:$O(logN + M)$
返回值:删除的元素member。

ZREMRANGBYSCORE key min max

zrangebyscore key 20 30
zhangsan 
zhaoliu

ZINCRBY

功能:为指定的元素关联的分数进行运算,也会同时移动元素位置,保持有序集合仍然是升序的。

ZINCRBY key increment member

127.0.0.1:6379> zadd key 10 zhangsan 20 lisi 30 wangwu 40 zhaouliu
4
127.0.0.1:6379> zincrby key 15 zhangsan
25

有序集合之间操作

ZINTERSTORE

ZINTERSTORE destination key [key...] [WEIGHTS weight [weight...]] [AGGREGATE <SUM | MIN | MAX>]

命令总结

数据结构 是否允许