redis有序集合也是集合类型的一部分,所以它保留了集合中元素不能重复的特性,但是不同的是,有序集合给每个元素多设置了一个分数,利用该分数作为排序的依据。
有序集合可以利用分数进行从小到大的排序。虽然有序集合的成员是唯一的,但是分数(score)却可以重复。就比如在一个班中,学生的学号是唯一的,但是每科成绩却是可以一样的,redis可以利用有序集合存储学生成绩快速做成绩排名功能。
常用命令
zadd 命令
描述:向一个有序集合中加入一个或者多个元素及其分数。假如加入的元素已经存在,那么更新这个成员的分数值,然后进行重新插入,来定位自己的位置。如果key不存在,那么创建一个新的有序集合并进行插入操作。
命令使用:[zadd 命令] [key 名称] [数值 field] [value 值]
127.0.0.1:6379> zadd score zhangsan 80 xiaoming 90 lisi 100
(error) ERR value is not a valid float
127.0.0.1:6379> zadd score 80 zhangsan 90 xiaoming 100 lisi
(integer) 3
127.0.0.1:6379>
zcard 命令
描述:用于计算有序集合中元素的数量。
命令使用:[zcard 命令] [key 名称]
127.0.0.1:6379> zcard score
(integer) 3
127.0.0.1:6379>
zcount 命令
描述:用于计算有序集合中指定分数区间的成员数量。
命令使用:[zcount命令] [key 名称] [field 开始的数值] [field 结束的数值]
127.0.0.1:6379> zcount score 80 90
(integer) 2
127.0.0.1:6379>
zrange 命令
描述: 用于返回指定区间内的成员。其中成员的位置按分数值递增(从小到大)来排序。这里的下标参数都是从0开始的,负数代表是从最后一个成员算起,-1表示最后一个成员。
命令使用:[zrange命令] [key 名称] [开始下标] [结束下标]
127.0.0.1:6379> zrange score 0 -1
1) "zhangsan"
2) "xiaoming"
3) "lisi"
127.0.0.1:6379>
ZREVEANGE 命令
描述:用于返回指定分数区间内的成员。其中成员的位置按分数值递减(从大到小)来排序。
命令使用:[ZREVEANGE 命令] [key 名称] [开始下标] [结束下标]
127.0.0.1:6379> ZREVRANGE score 0 -1
1) "lisi"
2) "xiaoming"
3) "zhangsan"
127.0.0.1:6379>
zrangebyscore 命令
描述:回有序集合中指定分数区间的成员列表。其中集成员按分数值递增(从小到大)来排序。
命令使用:[zrangebyscore 命令] [key 名称] [开始数值] [结束数值]
127.0.0.1:6379> zrangebyscore score 80 90
1) "zhangsan"
2) "xiaoming"
127.0.0.1:6379>
zrank 命令
描述:用于返回有序集中指定成员的排名。
命令使用:[zrank 命令] [key 名称] [value 值]
127.0.0.1:6379>
127.0.0.1:6379> zrank score xiaoming
(integer) 1
127.0.0.1:6379> zrank score zhangsan
(integer) 0
127.0.0.1:6379> zrank score lisi
(integer) 2
127.0.0.1:6379>
zrem 命令
描述:用于移除有序集中的一个或多个成员,不存在的成员将被忽略。
命令使用:[zrem 命令] [key 名称] [value 值]
127.0.0.1:6379> zrem score xiaoming
(integer) 1
127.0.0.1:6379> zrange score 0 -1
1) "zhangsan"
2) "lisi"
127.0.0.1:6379>
zremrangebyrank 命令
描述:用于移除有序集中,指定排名(rank)区间内的所有成员。
命令使用:[zremrangebyrank 命令] [key 名称] [开始下标] [结束下标]
127.0.0.1:6379> zremrangebyrank score 0 0
(integer) 1
127.0.0.1:6379> zrange score 0 -1
1) "lisi"
127.0.0.1:6379>
zscore 命令
描述:返回有序集中,成员的分数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil。
命令使用:[zscore 命令] [key 名称] [value 值]
127.0.0.1:6379> zadd score 66 xiaohe
(integer) 1
127.0.0.1:6379> zscore score xiaohe
"66"
127.0.0.1:6379>
zscan 命令
描述:用于迭代有序集合中的元素(包括元素成员和元素分值)。
命令使用:[zscan 命令] [key 名称] [游标值] [匹配模式] [查找的内容 x* 代表 x开头的内容]
127.0.0.1:6379> zscan score 0 match x*
1) "0"
2) 1) "xiaohe"
2) "66"
127.0.0.1:6379>
一、排行榜
有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。
下面是一个简单的实现代码(仅供参考):
$product = [
'status' => 0,
'id' => 1
];
// 判断商品的状态
if ($product['status'] == 1){
throw new \Exception("商品未上架");
}
// 判断商品ID的访问量的统计是否存在
if (!Redis::exists("product:".$product['id'].":count")){
// 不存在 set 创建一个
Redis::set("product:".$product['id'].":count",1);
}else{
// 存在 数量 +1
Redis::incr("product:".$product['id'].":count",1);
}
// zadd 更新有序集合的浏览量
Redis::zadd("product:Ranking",Redis::get("product:".$product['id'].":count"),$product['id']);
?>
为了更好的突出效果,商品每被浏览一次,redis 就使用 string 进行一次记录,同时 zset 类型会根据 string 的记录对相关商品的分数进行修改,保证商品排行的实时更新。
在用户查看排行榜时:
127.0.0.1:6379> ZREVRANGE product:Ranking 0 -1
1) "2"
2) "1"