zoukankan      html  css  js  c++  java
  • Redis学习日记-05:SORT命令

    前言

    在进行数据排序的时候很容易想到使用ZSET(有序集合)。然而有序集合常见的使用场景是大数据排序,如游戏玩家排行榜等,所以很少获取键中的全部数据。然而在Redis中对数据的排序除了用有序集合外还可以使用SORT命令。
    SORT命令可以对列表、集合、有序集合类型的键进行排序。

    命令&选项

    以列表类型为例:

    127.0.0.1:6379> lrange post 0 -1
    1) "2"
    2) "1"
    3) "3"
    

    SORT(默认根据元素由小到大):

    127.0.0.1:6379> sort post
    1) "1"
    2) "2"
    3) "3"
    

    DESC(逆序):

    127.0.0.1:6379> sort post desc
    1) "3"
    2) "2"
    3) "1"
    

    在SORT命令后面加上DESC选项即可将元素逆序排序

    ALPHA(非数字元素排序):

    127.0.0.1:6379> lrange strlist 0 -1
    1) "d"
    2) "B"
    3) "C"
    4) "b"
    5) "A"
    

    加上ALPHA选项(如果不加该选项会报错:(error) ERR One or more scores can't be converted into double)

    127.0.0.1:6379> sort strlist alpha
    1) "A"
    2) "b"
    3) "B"
    4) "C"
    5) "d"
    

    该选项会按照字典顺序排序。

    BY(参考键):

    示例1

    127.0.0.1:6379> hget post:1 count
    "10"
    127.0.0.1:6379> hget post:2 count
    "15"
    127.0.0.1:6379> hget post:3 count
    "5"
    127.0.0.1:6379> lrange post 0 -1
    1) "2"
    2) "1"
    3) "3"
    127.0.0.1:6379> sort post by post:*->count
    1) "3"
    2) "1"
    3) "2"
    

    实例2(某个参考键不存在的情况)

    127.0.0.1:6379> lrange post 0 -1
    1) "4"
    2) "2"
    3) "1"
    4) "3"
    127.0.0.1:6379> hget post:4 count
    (nil)
    127.0.0.1:6379> sort post by post:*->count
    1) "4"
    2) "3"
    3) "1"
    4) "2"
    
    • 该选项可以指定一个参考键(该参考键可以是字符串类型键或者散列类型键的某个字段)来进行排序,而不按照待排序键的元素大小排序。
      如上所示,BY选项后面的参数“post:->count”,表示按照“post:”开头的散列的count字段排序,过程中会用待排序键的元素替换“”,即先分别取到post:2、post:1、post:3的count字段的值,分别为15、10、5,并按该值由小到大排序(5,10,15)->(post:3,post:1,post:2),最后返回对应的待排序中的元素(3,1,2)。
    • 如果参考键是一个常量键或者不存在的键,则SORT的结果和LRANGE的结果相同,没有执行排序操作。常量键指的是不包含“*”,如“post:1->count”。
    • 如果参考键值相同,即如果上述post:1、post:2、post:3的count字段值相同,则SORT会按照待排序键元素本身来排序。
    • 如果某个元素对应的参考键不存在,则默认参考键的值为0。如上示例2,post:4这个散列并不存在,但是post中元素中加入了4,则排序会按照由小到大(0(post:4默认),5,10,15)->(post:4,post:3,post:1,post:2),最后返回对应的待排序中的元素(4,3,1,2)。

    LIMIT(返回指定范围的结果):

    127.0.0.1:6379> lrange post 0 -1
    1) "4"
    2) "2"
    3) "1"
    4) "3"
    127.0.0.1:6379> sort post limit 1 3
    1) "2"
    2) "3"
    3) "4"
    

    LIMIT选项后面可以跟两个参数,一个是offset,代表从那个位置开始;另一个是count,代表取多少个元素。和Mysql的LIMIT语法很像。

    GET(指定排序之后的返回数据):

    示例1

    127.0.0.1:6379> sort post by post:*->count get post:*->time
    1) (nil)
    2) "423"
    3) "123"
    4) "234"
    

    实例2

    127.0.0.1:6379> sort post by post:*->count get post:*->time get #
    1) (nil)          ---post:*->time代表的值
    2) "4"            ---元素本身的值
    3) "423"
    4) "3"
    5) "123"
    6) "1"
    7) "234"
    8) "2"
    
    • 实例1可以看到上面SORT命令后面跟了“get post:->time”,意思是该排序不返回待排序键元素本身,而是返回指定的以“post:”开头的散列类型键的time字段。
    • 你也可以使用“get #”来使其返回待排序键元素本身,如上示例2,依次输出GET选项对应的值。
    • SORT后面BY选项只能有一个,但是GET选项可以有多个。

    STORE(将排序结果存入另一个键中)

    针对上面GET命令示例2中的数据,再附加STORE选项:

    127.0.0.1:6379> sort post by post:*->count get post:*->time get # store sort:result
    (integer) 8
    127.0.0.1:6379> type sort:result
    list
    127.0.0.1:6379> lrange sort:result 0 -1
    1) ""
    2) "4"
    3) "423"
    4) "3"
    5) "123"
    6) "1"
    7) "234"
    8) "2"
    

    可以看到STORE选项后面跟了一个参数键sort:result,这个键可以是之前不存在的,命令执行后,会将排序返回的结果存放到该键中以列表的形式存在。

    总结

      SORT是Redis最强大的命令之一,如果使用不当会造成性能瓶颈。SORT的时间复杂度为O(n+mlog(m)),其中n表示待排序元素的数量,m表示返回的元素数量。当n很大时,Redis在排序前建立一个长度为n的容器来存储待排序元素,因此同时进行大数据量的排序不管是在时间还是空间上消耗很多,从而降低性能。
      因此使用SORT命令时应该注意以下几点:

    1. 尽可能减少待排序键中的元素;
    2. 尽可能减少排序之后返回的数据,你可以使用上面提到的LIMIT选项来控制;
    3. 如果排序返回的结果较多,尽可能使用上面提到的STORE将排序结果缓存起来。
  • 相关阅读:
    Python环境下如何安装爬虫需求的一些库
    (转)在.net中检索HTTP请求
    MyEclipse反编译插件下载地址
    Intellij Idea创建SpringBoot项目使用内置Tomcat能成功访问,将项目war包部署至第三方Tomcat访问出现404问题及解决方案
    解决Windows 10 Tomcat命令行窗口中文乱码
    springboot打包错误:Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0...
    JPA使用IDEAR生成映射实体
    EclipseJVM调优设置
    SpringBoot eureka 工作原理(转 Eureka服务发现注册之使用ip地址注册eureka服务详解)
    oracle行转列/列转行/字符串拆分 测试
  • 原文地址:https://www.cnblogs.com/xuxiaojian/p/9559989.html
Copyright © 2011-2022 走看看