有序集合-zset
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
有序集合命令
-
ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,如果成员已存在则更新分数,返回成功操作的成员个数$redis->zAdd('rank','5','10000','5','10000','6','10000','8','10001');//2
-
ZCARD key
获取有序集合的成员数$redis->zCard('rank');//2
-
ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合指定区间内的成员,[withscores=false] 设置为true时返回score$redis->zRange('rank',0,-1); //array ( // 0 => '10000', // 1 => '10001', //) $redis->zRange('rank',0,-1,true); //array ( // 10000 => 6.0, // 10001 => 8.0, //)
-
ZRANK key member
返回有序集合中指定成员的索引$redis->zRank('rank' ,'10001');
-
ZREVRANK key member
返回成员的在集合中的排名,有序集成员按分数值递减(从大到小)排序$redis->zRevRank('rank',10000);
-
ZREM key member [member ...]
移除有序集合中的一个或多个成员$redis->zRem('rank' ,'10001'); //再用zRank查看成员10001的索引 返回false 表示已经被删除了 $redis->zRank('rank' ,'10001');//false
-
zRevRangeByScore key min max [WITHSCORES] [LIMIT]
返回有序集中指定分数区间的成员列表,按分数值递增排序$redis->zAdd('rank',60,'99999','65','99998','100','99997'); $result =$redis->zRangeByScore('rank',0,100); [WITHSCORES]返回score [LIMIT] 自定义返回的序集返回起始位置及条数 $result =$redis->zRangeByScore('rank',0,100,['withscores'=>true,'limit'=>[1,2]]); //array ( // 99999 => 60.0, // 99998 => 65.0, //)%
-
ZINCRBY key increment member
有序集合中对指定成员的分数加上指定增量,如果成员不存在则自动创建$result = $redis->zIncrBy('rank',50,'88888'); $result = $redis->zIncrBy('rank',8,'88888');//58
-
ZINTERSTORE destination numkeys key [key ...]
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中,元素相加,并将其存储到目的有序集中$redis->zAdd('zset1',10,'001',20,'002',30,'003'); $redis->zAdd('zset2',100,'001',200,'002',300,'003',400,'004'); $result=$redis->zinterstore('zinter',['zset1','zset2']);//3 $result=$redis->zRange('zinter',0,-1,true); //array ( // '001' => 110.0, // '002' => 220.0, // '003' => 330.0, //)
-
ZUNIONSTORE destination numkeys key [key ...]
//计算给定一个或多个有序集的并集,元素相加,并将其存储到目的有序集中$result = $redis->zunionstore('zunion',['zset1','zset2']);//4 $result=$redis->zRange('zunion',0,-1,true); //array ( // '001' => 110.0, // '002' => 220.0, // '003' => 330.0, // '004' => 400.0, //)
使用场景
有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。本节使用赞数这个维度,记录每天用户上传视频的排行榜。主要需要实现以下4个功能。
1.添加用户赞数
例如用户mike上传了一个视频,并获得了3个赞,可以使用有序集合的 zadd和zincrby功能:
zadd user:ranking:2016_03_15 mike 3 如果之后再获得一个赞,可以使用zincrby:
zincrby user:ranking:2016_03_15 mike 1
2取消用户赞数
由于各种原因(例如用户注销、用户作弊)需要将用户删除,此时需要将用户从榜单中删除掉,可以使用zrem。例如删除成员tom:
zrem user:ranking:2016_03_15 mike
3.展示获取赞数最多的十个用户
此功能使用zrevrange命令实现: zrevrangebyrank user:ranking:2016_03_15 0 9
4.展示用户信息以及用户分数
此功能将用户名作为键后缀,将用户信息保存在哈希类型中,至于用户
的分数和排名可以使用zscore和zrank两个功能:
hgetall user:info:tom zscore user:ranking:2016_03_15 mike zrank user:ranking:2016_03_15 mike