Redis系列六、redis的五种数据结构和相关指令之Sorted Set

本节中将介绍Redis支持的主要数据结构,以及相关的常用Redis命令。redis是一种基于键值对(key-value)的内存数据库,redis数据结构可以分为string、hash、list、set、sorted set。

redis的五种数据结构和相关指令之有序集合sorted set

有序集合sorted set

有序集合与集合一样,元素都不能重复;Sorted Set中的每个元素都需要指派一个分数(score),Sorted Set会根据score对元素进行升序排序。如果多个member拥有相同的score,则以字典序进行升序排序。
常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数与集合有联系,不能有重复的成员。
Redis系列六、redis的五种数据结构和相关指令之Sorted Set

与LIST和SET对比

Redis系列六、redis的五种数据结构和相关指令之Sorted Set

1、常用命令

Redis系列六、redis的五种数据结构和相关指令之Sorted Set

2、增删指令

添加指令

zadd key [NX|XX] [CH] [INCR] score member [score member…]

  • XX: 仅仅更新存在的成员,不添加新成员。

  • NX: 不更新存在的成员。只添加新成员。

  • CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量,注意: 如果和incr一起使用的时候,返回的会是incr的结果。

  • INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。

    zadd user:3 200 james //james的点赞数1, 返回操作成功的条数1
    zadd user:3 200 james 120 mike 100 lee// 返回3
    
    zadd test:1 nx 100 james   //键test:1必须不存在,主用于添加
    zadd test:1 xx incr 200 james   //键test:1必须存在,主用于修改,此时为300
    zadd test:1 xx ch incr -299 james //返回操作结果1,300-299=1
    zrange test:1 0 -1 withscores  //查看点赞(分数)与成员名
    

增加分数

zincrby user:3 10 lee     //成员lee的分数加10
zadd user:3 xx incr 10 lee //和上面效果一样

删除指令

zrem user:zan jame mike //返回成功删除2个成员,还剩lee

删除指定排名内的升序元素:

zremrangebyrank user:3 0 1 //分数升序排列,删除第0个与第1个,只剩james

删除指定分数范围的成员

zadd user:5 200 james 120 mike 100 lee//先插入测试数据
zremrangebyscore user:5 100 300     //删除分数在100与300范围的成员
zremrangebyscore user:5 (100 +inf    //删除分数大于100(不包括100),还剩lee

3、查看指令

查看分数

zscore user:3 james     //查看james的点赞数(分数),返回200

查看排名

zrank user:3 james  //返回名次:第3名返回2,从0开始到2,共3名
zrevrank user:3 james //返回0, 反排序,点赞数越高,排名越前

返回指定排名范围的分数与成员

zadd user:4 200 james 120 mike 100 lee//先插入数据
zrange user:4 0 -1 withscores //返回结果如下图

Redis系列六、redis的五种数据结构和相关指令之Sorted Set

zrevrange user:4 0 -1 withscores   //倒序,结果如下图

Redis系列六、redis的五种数据结构和相关指令之Sorted Set

返回指定分数范围的成员

zrangebyscore user:4 110 300 withscores //返回120 lee ,200 James, 由低到高 
zrevrangebyscore user:4 300 110 withscores //返回200james 120lee,由高到低
 
zrangebyscore user:4 (110 +inf withscores//110到无限大,120mike 200james 
zrevrangebyscore user:4 (110 -inf withscores//无限小到110,返回100 lee

返回指定分数范围的成员个数:

zcount user:4 110 300  //返回2,由mike120和james200两条数据

统计成员数量

zcard test:1     //计算成员个数, 返回1

4、有序集合交集

格式:

zinterstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
  • destination:交集产生新的元素存储键名称。
  • numkeys: 要做交集计算的键个数,匹配不上会有语法错误,会执行不了。
  • key :元素键值。
  • weights:每个被选中的键对应值乘weight, 默认为1。

初始化数据:

zadd user:7 1 james 2 mike 4 jack 5 kate      //初始化user:7数据
zadd user:8 3 james 4 mike 4 lucy 2 lee  6 jim  //初始化user:8数据

交集例子:

 zinterstore user_jj 2 user:7 user:8 aggregate sum //2代表键合并个数,
//aggregate sum可加也不可加上,因为默认是sum
//结果user_jj:4james(1+3), 6mike(2+4) 

zinterstore user_jjmax 2 user:7 user:8 aggregate max 或min 
//取交集最大的分数,返回结果 3james  4mike, min取最小

weights的使用:

zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max
//1,取两个成员相同的交集,user:7->1 james  2 mike;  user:8->3 james  4 mike
//2,将user:7->james 1*8=8,  user:7->mike 2*8 =16, 最后user:7结果 8 james  16 mike; 
//3,将user:8-> james 3*4=12, user:8->mike 4*4=16,最后user:8结果12 james  16 mike
//4,最终相乘后的结果,取最大值为  12 james 16mike
//5, zrange user_jjweight 0 -1 withscores 查询结果为  12 james 16mike

5、有序集合并集(合并去重)

格式:

zunionstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
  • destination:交集产生新的元素存储键名称
  • numkeys: 要做交集计算的键个数 key :元素键值
  • weights:每个被选中的键对应值乘weight, 默认为1

eg:

zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max
//与以上zinterstore一样,只是取并集,指令一样

6、有序集合应用场景

排行榜系统,如视频网站需要对用户上传的视频做排行榜
点赞数:

zadd user:1:20180106 3 mike  //mike获得3个赞

再获一赞:

zincrby user:1:20180106 1 mike  //在3的基础上加1

用户作弊,将用户从排行榜删掉:

zrem user:1:20180106 mike

展示赞数最多的5个用户:

zrevrangebyrank user:1:20180106  0  4 

查看用户赞数与排名:

zscore user:1:20180106 mike   
zrank user:1:20180106 mike