ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

redis有序集合sorted set(zset)数据类型相关命令介绍及使用

2022-01-17 10:02:00  阅读:172  来源: 互联网

标签:127.0 score zset 0.1 成员 数据类型 6379 set key


文章目录

简介

  1. Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
  2. 有序集合的成员是唯一的,但分数(score)却可以重复。
  3. 集合是通过两种底层数据结构实现的。一种是ziplist压缩列表,另一种就是redis中最经典的数据结构skipList跳跃表,所以添加,删除,查找的复杂度都是 O(1)。
  4. 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

添加命令

  1. zadd key [nx|xx] [CH] [INCR] score member [score member ...]
    在有序集合中添加元素,如果元素已经存在,则会更新其score;如果该有序集合不存在,则直接创建并添加相应的元素;如果key不为sorted set 类型,则报错。
    分数score 为双精度的浮点型数字字符串。
    NX:不更新存在的成员。只添加新成员;
    XX:仅更新存在的成员,不添加新成员;
    CH:成员不存在就添加,存在就更新分值,返回值为分值发生变化的成员总数;分数不变不计算;
    INCR:指定这个选项的时候,命令等于zincrby命令,对成员的分数进行递增操作,返回操作后的分值
    //英语成绩,张三60分,李四70分,王五90分
    127.0.0.1:6379> zadd english_score 60 zhangsan 70 lisi 90 wangwu
    (integer) 3
    127.0.0.1:6379> zrange english_score 0 -1 withscores
    1) "zhangsan"
    2) "60"
    3) "lisi"
    4) "70"
    5) "wangwu"
    6) "90"
    //NX:不更新存在的成员。只添加新成员
    //张三已存在,所以返回0
    127.0.0.1:6379> zadd english_score nx 70 zhangsan
    (integer) 0
    127.0.0.1:6379> zadd english_score nx 60 xiaoming
    (integer) 1
    //XX:仅更新存在的成员,不添加新成员
    127.0.0.1:6379> zadd english_score xx 60 zhaoliu
    (integer) 0
    127.0.0.1:6379> zadd english_score xx 70 zhangsan
    (integer) 0
    //张三存在分数改为70,赵六不存在无操作
    127.0.0.1:6379> zrange english_score 0 -1 withscores
    1) "xiaoming"
    2) "60"
    3) "lisi"
    4) "70"
    5) "zhangsan"
    6) "70"
    7) "wangwu"
    8) "90"
    //CH:成员不存在就添加,存在就更新分值,返回值为分值发生变化的成员总数;分数不变不计算;
    //张三分数改为80,添加赵六分数为75.5
    127.0.0.1:6379> zadd english_score ch 80 zhangsan 75.5 zhaoliu
    (integer) 1
    127.0.0.1:6379> zrange english_score 0 -1 withscores
     1) "xiaoming"
     2) "60"
     3) "lisi"
     4) "70"
     5) "zhaoliu"
     6) "75.5"
     7) "zhangsan"
     8) "80"
     9) "wangwu"
    10) "90"
    //INCR:指定这个选项的时候,命令等于zincrby命令,对成员的分数进行递增操作,返回操作后的分值
    //张三分数+5
    127.0.0.1:6379> zadd english_score incr 5 zhangsan
    "85"
    127.0.0.1:6379> zrange english_score 0 -1 withscores
     1) "xiaoming"
     2) "60"
     3) "lisi"
     4) "70"
     5) "zhaoliu"
     6) "75.5"
     7) "zhangsan"
     8) "85"
     9) "wangwu"
    10) "90"
    
    

查询命令

  1. zcard key
    获取有序集合的成员数
    127.0.0.1:6379> zcard english_score
    (integer) 3
    
  2. zscore key member
    返回有序集中,成员的分数值
    127.0.0.1:6379> zscore english_score lisi
    "70"
    

递增类型

  1. zrange key start stop [WITHSCORES]
    按分值递增排序,通过索引区间返回有序集合指定区间内的成员,withscores为输出结果带分数

    127.0.0.1:6379> zrange english_score 0 -1 
    1) "zhangsan"
    2) "lisi"
    3) "wangwu"
    127.0.0.1:6379> zrange english_score 0 -1 withscores
    1) "zhangsan"
    2) "60"
    3) "lisi"
    4) "70"
    5) "wangwu"
    6) "90"
    
  2. zrangebylex key min max [LIMIT offset count]
    通过字典区间返回有序集合的成员。
    min:字典中排序位置较小的成员,必须以”[“开头,或者以”(“开头,可使用”-“代替
    max:字典中排序位置较大的成员,必须以”[“开头,或者以”(“开头,可使用”+”代替
    limit:返回结果是否分页,指令中包含LIMIT后offset、count必须输入
    offset:返回结果起始位置
    count:返回结果数量

    注意:

    1. 不要在分数不一致的SortSet集合中去使用 ZRANGEBYLEX 指令,因为获取的结果并不准确。
    2. 成员字符串作为二进制数组的字节数进行比较。
    3. 默认是以ASCII字符集的顺序进行排列。如果成员字符串包含utf-8这类字符集的内容,就会影响返回结果,所以建议不要使用。
    4. 默认情况下, “max” 和 “min” 参数前必须加 “[” 符号作为开头。”[” 符号与成员之间不能有空格, 返回成员结果集会包含参数 “min” 和 “max” 。
    5. “max” 和 “min” 参数前可以加 “(” 符号作为开头表示小于, “(” 符号与成员之间不能有空格。返回成员结果集不会包含 “max” 和 “min” 成员。
    6. 可以使用 “-” 和 “+” 表示得分最小值和最大值
    7. “min” 和 “max” 不能反, “max” 放前面 “min”放后面会导致返回结果为空
    8. 与ZRANGEBYLEX获取顺序相反的指令是ZREVRANGEBYLEX。
    9. 源码中采用C语言中memcmp() 函数, 从字符的第0位到最后一位进行排序,如果前面部分相同,那么较长的字符串比较短的字符串排序靠后。
    127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g
    (integer) 7
    127.0.0.1:6379> ZRANGEBYLEX myzset - [c
    1) "a"
    2) "b"
    3) "c"
    127.0.0.1:6379> ZRANGEBYLEX myzset - (c
    1) "a"
    2) "b"
    127.0.0.1:6379> ZRANGEBYLEX myzset [aaa (g
    1) "b"
    2) "c"
    3) "d"
    4) "e"
    5) "f"
    
  3. zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
    按分值递增排序,通过分数区间返回有序集合指定区间内的成员

    127.0.0.1:6379> zrangebyscore english_score 60 80 withscores
    1) "xiaoming"
    2) "60"
    3) "lisi"
    4) "70"
    5) "zhaoliu"
    6) "75.5"
    
  4. zrank key member
    有序集成员按分数值递增(从小到大)排序,返回有序集合中指定成员的排名索引

    127.0.0.1:6379> zrange english_score 0 -1 
    1) "xiaoming"
    2) "lisi"
    3) "zhaoliu"
    4) "zhangsan"
    5) "wangwu"
    //zhangsan的索引是3
    127.0.0.1:6379> zrank english_score zhangsan
    (integer) 3
    

递减类型

  1. zrevrange key start stop [WITHSCORES]
    按分值递减排序,通过索引返回有序集中指定区间内的成员,分数从高到低
    127.0.0.1:6379> zrevrange english_score 0 -1 withscores
     1) "wangwu"
     2) "90"
     3) "zhangsan"
     4) "85"
     5) "zhaoliu"
     6) "75.5"
     7) "lisi"
     8) "70"
     9) "xiaoming"
    10) "60"
    
  2. zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
    按分值递减排序,返回指定分数区间内有序集的成员,分数从高到低排序
    127.0.0.1:6379> zrevrangebyscore english_score 80 70 withscores
    1) "zhaoliu"
    2) "75.5"
    3) "lisi"
    4) "70"
    
  3. zrevrank key member
    有序集成员按分数值递减(从大到小)排序,返回有序集合中指定成员的排名索引
    127.0.0.1:6379> zrevrange english_score 0 -1 
    1) "wangwu"
    2) "zhangsan"
    3) "zhaoliu"
    4) "lisi"
    5) "xiaoming"
     127.0.0.1:6379> zrevrank english_score zhangsan
    (integer) 1
    127.0.0.1:6379> zrevrank english_score lisi
    (integer) 3
    

删除命令

  1. zrem key member [member ...]
    移除有序集合中的一个或多个成员
    127.0.0.1:6379> zrevrange english_score 0 -1
    1) "wangwu"
    2) "zhangsan"
    3) "zhaoliu"
    4) "lisi"
    5) "xiaoming"
    127.0.0.1:6379> zrem english_score xiaoming
    (integer) 1
    127.0.0.1:6379> zrevrange english_score 0 -1
    1) "wangwu"
    2) "zhangsan"
    3) "zhaoliu"
    4) "lisi"
    
  2. zremrangebylex key min max
    移除有序集合中给定的字典区间的所有成员,返回被成功移除的成员的数量,不包括被忽略的成员。
  3. zremrangebyrank key start stop
    移除有序集合中给定的排名区间的所有成员
  4. zremrangebyscore key min max
    移除有序集合中给定的分数区间的所有成员

运算命令

  1. zcount key min max
    计算在有序集合中指定区间分数的成员数

    127.0.0.1:6379> zrevrange english_score 0 -1 withscores
    1) "wangwu"
    2) "90"
    3) "zhangsan"
    4) "85"
    5) "zhaoliu"
    6) "75.5"
    7) "lisi"
    8) "70"
    //80-90分的有两个,张三和王五
    127.0.0.1:6379> zcount english_score 80 90
    (integer) 2
    
  2. zlexcount key min max
    在有序集合中计算指定字典区间内成员数量

    127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e
    (integer) 5
    127.0.0.1:6379> ZADD myzset 0 f 0 g
    (integer) 2
    127.0.0.1:6379> ZLEXCOUNT myzset - +
    (integer) 7
    127.0.0.1:6379> ZLEXCOUNT myzset [b [f
    (integer) 5
    
  3. zincrby key increment member
    有序集合中对指定成员的分数加上增量 increment
    可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
    当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
    当 key 不是有序集类型时,返回一个错误。
    分数值可以是整数值或双精度浮点数。

    127.0.0.1:6379> zincrby english_score 0.5 zhaoliu
    "76"
    
  4. zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
    命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
    默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
    WEIGHTS:使用 WEIGHTS 选项,你可以为每个给定有序集分别指定一个乘法因子(multiplication factor),每个给定有序集的所有成员的 score 值在传递给聚合函数(aggregation function)之前都要先乘以该有序集的因子。
    AGGREGATE:使用 AGGREGATE 选项,你可以指定并集的结果集的聚合方式。
    默认使用的参数 SUM ,可以将所有集合中某个成员的 score 值之 和 作为结果集中该成员的 score 值;使用参数 MIN ,可以将所有集合中某个成员的 最小 score 值作为结果集中该成员的 score 值;而参数 MAX 则是将所有集合中某个成员的 最大 score 值作为结果集中该成员的 score 值。

    //有序集 mid_test
    127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
    (integer) 1
    127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
    (integer) 1
    127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
    (integer) 1
    
    //另一个有序集 fin_test
    127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
    (integer) 1
    127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
    (integer) 1
    127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
    (integer) 1
    
    //交集
    127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
    (integer) 3
    
    //显示有序集内所有成员及其分数值
    127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES     
    1) "Han Meimei"
    2) "145"
    3) "Li Lei"
    4) "158"
    5) "Tom"
    6) "199"
    
  5. zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
    命令计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。
    默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 。

    127.0.0.1:6379> zadd zset1 1 one 2 two
    (integer) 2
    127.0.0.1:6379> zadd zset2 1 one 2 two 3 three
    (integer) 3
    127.0.0.1:6379> zunionstore out 2 zset1 zset2 WEIGHTS 2 3
    (integer) 3
    127.0.0.1:6379> zrange out 0 -1 withscores
    1) "one"
    2) "5"
    3) "three"
    4) "9"
    5) "two"
    6) "10"
    

skiplist

本质是一种查找结构,用于解决算法中的查找问题,根据给定的key快速查找到它所在位置,是对有序链表的优化,查找的效率一般为O(logn)。
例子:

  1. 在普通有序链表中查找一个数据,我们要从头查找,时间复杂度是O(n)
  2. 在普通链表之上,若我们隔一个,生成一个新的链表,这样如果我要查找23流程如下
    2.1 23首先和7比较,再和19比较,比它们都大,继续向后比较。
    2.2 但23和26比较的时候,比26要小,因此回到下面的链表(原链表),与22比较。
    2.3 比22要大,沿下面的指针继续向后和26比较。23比26小,说明待查数据23在原链表中不存在,而且它的插入位置应该在22和26之间。

在这里插入图片描述
由于新增的指针,我们不需要跟链表中每个节点进行比较,而是先跳跃着比较,缩小比较范围,再进行查找增加了查找的效率,在二层之上,我们还可以添加三层,四层,skiplist正式由此启发而诞生的数据结构。

为了插入节点方便,skiplist不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是针对每个节点随机出一个层数,以下是一个skiplist生成的过程。
在这里插入图片描述
若要在这样的跳表查找23,流程如下:

  1. 在最上层找,找到7,比7大在向右找,null没有了;
  2. 在7节点向下一层,在向右找,找到37,比较比37小;
  3. 在37节点下向下一层,向左找,找到19,比19大;
  4. 在19节点向下,向右找,找到22,比22大;
  5. 在22向右找,找到26,比26小;
  6. 那么23就在22和26之间插入
    在这里插入图片描述

标签:127.0,score,zset,0.1,成员,数据类型,6379,set,key
来源: https://blog.csdn.net/weixin_45240169/article/details/122511459

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有