特点: 集合内的元素不能重复,但可以排序。它的排序和列表使用索引作为排序依据不同,它给每个元素设置一个分数(score)作为排序依据,有序集合提供了获取指定分数和元素范围查询,计算成员排名等功能。
集合内:
1、添加成员
zadd key [nx|xx] [ch] [incr] score member [score2 member2 ....]
zadd命令参数需要注意:
nx: member必须不存在,才可以设置成功,用于添加
xx: member必须存在,才能可以设置成功,用于更新
ch: 返回此次操作后,有序集合元素和分数发生变化的个数
incr:对score做增加,相当于后面介绍的zincrby(对已经存在于集合的元素进行累加)
有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间复杂度为O(log(n)),sadd的时间复杂度为O();
incr参数的使用(集合中本是20,incr后变成22):
127.0.0.1:6379> zrange emp 0 -1 withscores
1) "wangwei"
2) "20"
3) "qq"
4) "22"
127.0.0.1:6379> zadd emp xx ch incr 2 wangwei
"22"
2、计算成员个数
zcard key
3、计算某个成员的分数,如果key不存在,返回nil
zscore key members
4、计算成员排名(从0开始,即第一名返回0)
zrank key member
zrevrank key member
zrank 是从分数从低到高排名,zreverank反之。
127.0.0.1:6379> zrevrank zadd wangs
(integer) 3
127.0.0.1:6379> zrank zadd wangs
(integer) 0
5、删除成员,返回删除成功数
zrem key member [member ...]
6、增加成员分数,返回增加后的分数
zincrby key increment member
127.0.0.1:6379> zincrby zadd 10 wangs
"11"
127.0.0.1:6379>
7、返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
有序集合是按照分值排名,zrange 是从低到高返回,zrevrange反之,如果加上withscores,同时会返回成员分数。
rar1) "wangs"
2) "11"
3) "wangwu"
4) "4"
5) "lisi"
6) "3"
7) "zhangsan"
8) "2"
127.0.0.1:6379> zrevrange key 0 5 //key集合 分数倒着输出,从大到小
1) "wangs"
2) "wangwu"
3) "lisi"
4) "zhangsan"
127.0.0.1:6379> zrange zadd 0 5 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "3"
5) "wangwu"
6) "4"
7) "wangs"
8) "11"
8、返回制定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key min max [withscores] [limit offset count]
其中zrangebyscore按照分数从低到高,zrevrangebyscore反之。withscores选项会返回每个成员分数。[limit offset count ]选项可以限制输出的起始位置和个数。
同时min 和max还支持开区间(小括号)和闭区间(不带括号), -inf 和 +inf 分别代表无限小和无限大
// 如下范围:2 到正无穷,不包括2,
127.0.0.1:6379>zrangebyscore zadd (2 +inf withscores
1) "lisi"
2) "3"
3) "wangwu"
4) "4"
5) "wangs"
6) "11"
//限制开始位置和数量
127.0.0.1:6379> zrangebyscore zadd (2 +inf withscores limit 1 2
1) "wangwu"
2) "4"
3) "wangwei"
4) "11"
//负无穷 到 2; 包括2;
127.0.0.1:6379> zrangebyscore zadd -inf 2 withscores
1) "zhangsan"
2) "2"
9、返回指定分数范围成员个数
zcount key min max
127.0.0.1:6379> zcount key 5 11
(integer) 1
127.0.0.1:6379>
10、删除指定排名内的升序元素
zremrangebyrank key srart end
//获取元素
127.0.0.1:6379> zrange zadd 0 5 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "3"
5) "wangwu"
6) "4"
7) "wangs"
8) "11"
127.0.0.1:6379>
//删除第3-4名成员(从0开始计算的,0为第一名)
127.0.0.1:6379> zremrangebyrank zadd 2 3
(integer) 2
127.0.0.1:6379> zrange zadd 0 5 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "3"
127.0.0.1:6379>
11、删除指定分数范围的成员
zremrangebyscore key min max
127.0.0.1:6379> zrange zadd 0 5 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "3"
127.0.0.1:6379> zremrangebyscore zadd (2 +inf
(integer) 1
127.0.0.1:6379> zrange zadd 0 5 withscores
1) "zhangsan"
2) "2"
127.0.0.1:6379>
一、 交集:
zinterstore destination numkeys key [key ...] [weights weight [weight ...] ] [aggregate sum|min|max]
参数说明:
desination :交集计算结果保存到这个键
numkeys:需要做交集计算键的个数
key [key ...] 需要做交集计算的键
weights weight [weight ... ] 每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1;
aggregate sum|min|max 计算成员交集后,分值可以按照不同集合的相同成员的分求 sum(和),min(最小值),max(最大值)做总汇,默认是sum;
1、如 a集合有成员 100 tom b集合有成员 200 tom 那么交集后默认为sum 则集合中为 300 tom
2、如a集合有成员 100 tom b集合有成员 300 tom 设置b集合权重 0.5,并且aggregate设置为max,则
交集后的值为: 150 tom (因为b的权重0.5 * 300 = 150 ,仍比a集合的100大,所以取较大的值)。
二、并集
zunionstore destination numkeys key [key ...] [weights weiths [weight ...]] [aggregate sum|min|max]
该命令所有参数和交集是一致的。
三、内部编码
有序集合类型的内部编码分为两种
ziplist(压缩列表) ,当有序集合的元素个数小于zset-max-ziplist-entries 配置(默认128个),同时每个元素的值都小于zset-ax-ziplist-value配置(默认64),redis会用ziplist来作为有序集合的内部编码,ziplist可以减小内存的使用
skiplist(跳跃表),当ziplist条件不满足时,有序集合会使用skiplist作为内部实现。因为此时ziplist的读写效率会下降。
四、使用场景
有序集合比较典型的使用场景:排行榜系统。如视频网站对用户上传的视频做排行榜,如按时间,按播放数量,按获得的赞数量等。
如:mike上传了一个视频,并获得了三个赞
zadd user:ranking:20180807 3 mike;
之后又获得了一个赞,使用zincrby;
zincrby user:ranking:20180807 1 mike;
由于某种原因,如mike作弊刷赞,需要将他从榜单移除
zrem user:ranking:20180807 mike;
展示获赞最大的十个用户
zrevrangebyrank user:ranging:20180807 0 9
展示用户信息以及用户分数
hgetall user:info:mike;//将用户信息保存哈希类型中
zscore user:ranking:20180807 mike;
zrank user:rangking:20180807 mike;