Redis数据结构之SortedSet
概述
Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管Sorted-Sets中的成员必须是唯一的,但是分数(score)却是可以重复的。
在Sorted-Set中添加、删除或更新一个成员都是非常快速的操作,其时间复杂度为集合中成员数量的对数。由于Sorted-Sets中的成员在集合中的位置是有序的,因此,即便是访问位于集合中部的成员也仍然是非常高效的。事实上,Redis所具有的这一特征在很多其它类型的数据库中是很难实现的,换句话说,在该点上要想达到和Redis同样的高效,在其它数据库中进行建模是非常困难的。
例如:游戏排名、微博热点话题等使用场景。
SortedSet相关功能(Redis客户端命令)
1)zadd key score member score2 member2 … :
将所有成员以及该成员的分数存放到sorted-set中,Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。
如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。
分数值可以是整数值或双精度浮点数。
如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
当 key 存在但不是有序集类型时,返回一个错误。
注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。
2)zcard key:
获取集合中的成员数量
3)zcount key min max:
获取分数在[min,max]之间的成员, 默认是闭区间; 想不包含可以: (min (max
4)zincrby key increment member:
设置指定成员的增加的分数。
Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment
可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
当 key 不是有序集类型时,返回一个错误。
分数值可以是整数值或双精度浮点数。
5)zrange key start end [withscores]:
获取集合中脚标为start-end的成员,[withscores]参数表明返回的成员包含其分数。排名以0开始
6)zrevrange key start stop [WITHSCORES])
返回指定排名之间的成员(结果是分数由高到低)
7)zrangebyscore key min max [withscores] [limit offset count]:
返回分数在[min,max]的成员并按照分数从低到高排序。[withscores]:显示分数;
[limit offset count]:offset,表明从脚标为offset的元素开始并返回count个成员。
8)zrevrangebyscore key max min [withscores] [limit offset count])
根据分数的范围获取成员(从高到低)
9)zrank key member:
返回成员在集合中的位置。返回一个成员的排名(从低到高的顺序)
10)zrevrank key member
返回一个成员的排名(从高到低)
11)zrem key member[member…]:
移除集合中指定的成员,可以指定多个成员。
12)zscore key member:
返回指定成员的分数
13)zremrangebyrank key start stop
根据排名进行删除
14)zremrangebyscore key min max
根据分数的范围进行删除
SortedSet相关功能(Jedis客户端API)
Redis java 客户端jedis
java测试代码如下,(maven项目的创建与pom.xml配置,还有jedis对象的创建都在redis数据结构之String)
/**
*SortedSet类型数据的API测试
*/
@Test
public void testSortedSet(){
HashMap<String, Double> scoreMembers = new HashMap<String, Double>();
scoreMembers.put("zhangsan",100.00);
scoreMembers.put("lisi",90.00);
scoreMembers.put("wangwu",80.00);
scoreMembers.put("zhaoliu",70.00);
scoreMembers.put("tianqi",60.00);
jedis.zadd("jedis-zset-key-01", scoreMembers);
//获取指定名词区间的所有成员,顺序为分数由低到高
Set<String> allMembers = jedis.zrange("jedis-zset-key-01", 0, -1);
System.out.println("所有的成员为:");
for(String m:allMembers){
System.out.println(m);
}
System.out.println("给赵六加40分之后,成员的排名情况为:");
//给指定的成员增加分数
jedis.zincrby("jedis-zset-key-01",40,"zhaoliu");
//获取指定名词区间的所有成员及关联的分数,顺序为分数由低到高
Set<Tuple> zrangeWithScores = jedis.zrangeWithScores("jedis-zset-key-01", 0, -1);
for(Tuple t:zrangeWithScores){
System.out.println(t.getElement()+":"+t.getScore());
}
System.out.println("按照分数由高到低的顺序打印排行榜:");
//获取指定名词区间的所有成员及关联的分数,顺序为分数由高到低
Set<Tuple> zrevrangeWithScores = jedis.zrevrangeWithScores("jedis-zset-key-01", 0, -1);
for(Tuple t:zrevrangeWithScores){
System.out.println(t.getElement()+":"+t.getScore());
}
}