目录sql
在进行数据排序的时候很容易想到使用ZSET(有序集合)。然而有序集合常见的使用场景是大数据排序,如游戏玩家排行榜等,因此不多获取键中的所有数据。然而在Redis中对数据的排序除了用有序集合外还可使用SORT命令。
SORT命令能够对列表、集合、有序集合类型的键进行排序。缓存
以列表类型为例:post
127.0.0.1:6379> lrange post 0 -1 1) "2" 2) "1" 3) "3"
127.0.0.1:6379> sort post 1) "1" 2) "2" 3) "3"
127.0.0.1:6379> sort post desc 1) "3" 2) "2" 3) "1"
在SORT命令后面加上DESC选项便可将元素逆序排序性能
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"
该选项会按照字典顺序排序。code
示例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:二、post:一、post:3的count字段的值,分别为1五、十、5,并按该值由小到大排序(5,10,15)->(post:3,post:1,post:2),最后返回对应的待排序中的元素(3,1,2)。
- 若是参考键是一个常量键或者不存在的键,则SORT的结果和LRANGE的结果相同,没有执行排序操做。常量键指的是不包含“*”,如“post:1->count”。
- 若是参考键值相同,即若是上述post:一、post:二、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)。
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语法很像。字符串
示例1get
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选项能够有多个。
针对上面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命令时应该注意如下几点: