⛄概述
Redis
的 SortedSet
是一个可排序的set集合,与Java中的TreeSet
有些类似,但底层数据结构却差别很大。SortedSet
中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)
加 hash表
。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
因为SortedSet 的可排序特性,经常被用来实现排行榜这样的功能。
⛄常见命令有
- ZADD key score member:添加一个或多个元素到sorted set ,如果已经存在则更新其score值
- ZREM key member:删除sorted set中的一个指定元素
- ZSCORE key member : 获取sorted set中的指定元素的score值
- ZRANK key member:获取sorted set 中的指定元素的排名
- ZCARD key:获取sorted set中的元素个数
- ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
- ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
- ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
- ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
- ZDIFF.ZINTER.ZUNION:求差集.交集.并集
注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可,例如:
- 升序获取sorted set 中的指定元素的排名:ZRANK key member
- 降序获取sorted set 中的指定元素的排名:ZREVRANK key memeber
⛄RedisTemplate API
❄️❄️ 向集合中插入元素,并设置分数
//1、通过redisTemplate设置值 redisTemplate.boundZSetOps("zSetKey").add("zSetVaule", 100D); //2、通过BoundValueOperations设置值 BoundZSetOperations zSetKey = redisTemplate.boundZSetOps("zSetKey"); zSetKey.add("zSetVaule", 100D); //3、通过ValueOperations设置值 ZSetOperations zSetOps = redisTemplate.opsForZSet(); zSetOps.add("zSetKey", "zSetVaule", 100D);
❄️❄️向集合中插入多个元素,并设置分数
DefaultTypedTuple<String> p1 = new DefaultTypedTuple<>("zSetVaule1", 2.1D); DefaultTypedTuple<String> p2 = new DefaultTypedTuple<>("zSetVaule2", 3.3D); redisTemplate.boundZSetOps("zSetKey").add(new HashSet<>(Arrays.asList(p1,p2)));
❄️❄️按照排名先后(从小到大)打印指定区间内的元素, -1为打印全部
Set<String> range = redisTemplate.boundZSetOps("zSetKey").range(0, -1);
❄️❄️获得指定元素的分数
Double score = redisTemplate.boundZSetOps("zSetKey").score("zSetVaule");
❄️❄️返回集合内的成员个数
Long size = redisTemplate.boundZSetOps("zSetKey").size();
❄️❄️返回集合内指定分数范围的成员个数(Double类型)
Long COUNT = redisTemplate.boundZSetOps("zSetKey").count(0D, 2.2D);
❄️❄️返回集合内元素在指定分数范围内的排名(从小到大)
Set byScore = redisTemplate.boundZSetOps("zSetKey").rangeByScore(0D, 2.2D);
❄️❄️带偏移量和个数,(key,起始分数,最大分数,偏移量,个数)
Set<String> ranking2 = redisTemplate.opsForZSet().rangeByScore("zSetKey", 0D, 2.2D 1, 3);
❄️❄️返回集合内元素的排名,以及分数(从小到大)
Set<TypedTuple<String>> tuples = redisTemplate.boundZSetOps("zSetKey").rangeWithScores(0L, 3L); for (TypedTuple<String> tuple : tuples) { System.out.println(tuple.getValue() + " : " + tuple.getScore()); }ss
❄️❄️返回指定成员的排名
//从小到大 Long startRank = redisTemplate.boundZSetOps("zSetKey").rank("zSetVaule"); //从大到小 Long endRank = redisTemplate.boundZSetOps("zSetKey").reverseRank("zSetVaule");
❄️❄️从集合中删除指定元素
redisTemplate.boundZSetOps("zSetKey").remove("zSetVaule");
❄️❄️删除指定索引范围的元素(Long类型)
redisTemplate.boundZSetOps("zSetKey").removeRange(0L,3L);
❄️❄️删除指定分数范围内的元素(Double类型)
redisTemplate.boundZSetOps("zSetKey").removeRangeByScorssse(0D,2.2D);
❄️❄️为指定元素加分(Double类型)
Double score = redisTemplate.boundZSetOps("zSetKey").incrementScore("zSetVaule",1.1D);
⛄应用场景
- 排行榜(Leaderboard): Sorted Set 是实现排行榜的理想选择。你可以将用户的分数作为元素的分数,用户的 ID(或者其他唯一标识符)作为元素的值,然后根据分数的高低来进行排名。
- 时间序列数据存储(Time Series Data): 如果你需要存储时间序列数据,并且需要按照时间顺序检索数据,Sorted Set 可以胜任这项任务。你可以将时间戳作为元素的分数,数据项作为元素的值,这样就可以按照时间顺序检索数据。
- 范围查询(Range Queries): 由于 Sorted Set 中的元素是按照分数有序排列的,你可以很容易地执行范围查询操作,比如获取分数在某个范围内的所有元素。
- 计数器(Counter): 类似于 Set,Sorted Set 也可以用作计数器。每次对某个元素的分数进行增加或减少,就相当于对计数器进行了加一或减一的操作。
- 任务调度(Task Scheduling): 可以使用 Sorted Set 来实现简单的任务调度系统。将任务的执行时间作为元素的分数,任务的唯一标识符作为元素的值,然后根据执行时间的顺序来提取要执行的任务。
- 范围查找(Range Retrieval): 类似于范围查询,但是这里更加注重于按照分数的范围查找元素。这在某些场景下可以帮助你快速定位需要处理的数据。
- 活跃用户列表(Active Users List): 使用 Sorted Set 来存储活跃用户的 ID,可以根据用户的活跃度(比如登录时间、活跃次数等)作为分数,然后根据活跃度来获取活跃用户列表。