Redis学习03–排序操作

9月 16th, 2012
Redis的排序操作

  1. redis支持对list, set和sorted set元素的排序;
  2. 排序命令SORT的语法:SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC|DESC] [ALPHA] [STORE destination];
  3. sort key [ASC|DESC] [ALPHA]:
    1. sort key:不加任何选项时就是简单的对列表自身元素排序,并返回排序结果,列表中的值只能是数字;
    2. ASC:sort默认的排序方式,即升序排列;
    3. DESC:是逆序排列;
    4. ALPHA:如果列表中是字符串或者数字的话,需要使用alpha选项按照字母顺序排列;ASC|DESC可以和ALPHA连用;
  4. [LIMIT offset count]:用于分页显示,表示从offset的位置(从0开始),显示count个记录;
  5. [BY nosort]:不排序,直接返回list, set或者sorted set中元素的物理顺序;
  6. [BY pattern]:使用外部的keys作为权重来对list, set, sorted set中的元素排序,但是权重的后缀必须与几何中的元素一一对应;
  7. [GET pattern …]:以通过get选项去获取指定pattern作为新key对应的值;
  8. [STORE destination]:如果对集合经常按照固定的模式去排序,那么把排序结果缓存起来会减少cpu的开销,使用store选项可以将排序内容保存到指定key中,保存的类型是list;
  9. 关于排序的两个问题及解决方案:
    1. 如果我们有多个redis server的话,不同的key可能存在于不同的server上,比如weight_3,weight_9, weight_12, weight_22很有可能分别在四个不同的server上存放着,这种情况会对排序性能造成很大的影响;
      1. 可以通过key tag将需要排序的key都放到同一个server上,由于具体决定哪个key存在哪个服务器上一般都是在client端hash的办法来做的,我们可以通过只对key的部分进行hash;
      2. 举个例子假如我们的client如果发现key中包含[],那么只对key中[]包含的内容进行hash,我们将weight_四个相关的key,[weight_]3,[weight_]9, [weight_]12, [weight_]22都这样命名,于是client程序就会把他们都放到同一server上;
    2. 如果要sort的集合非常大的话排序就会消耗很长时间,由于redis单线程的,所以长时间的排序操作会阻塞其他client的请求;
      1. 通过主从复制机制将数据复制到多个slave上,然后我们只在slave上做排序操作,并进可能的对排序结果缓存;
      2. 或者是采用sorted set对需要按某个顺序访问的集合建立索引;
  10. 实际使用的场景及例子;
——————————— sort key [ASC|DESC] [ALPHA] ———————————
— 1.sort key;
redis 127.0.0.1:6379> lpush l1 12
(integer) 1
redis 127.0.0.1:6379> lpush l1 3
(integer) 2
redis 127.0.0.1:6379> lpush l1 22
(integer) 3
redis 127.0.0.1:6379> lpush l1 9
(integer) 4
redis 127.0.0.1:6379> sort l1
1) “3”
2) “9”
3) “12”
4) “22”
redis 127.0.0.1:6379> sort l1 desc
1) “22”
2) “12”
3) “9”
4) “3”
— 2.alpha;
1.对数字按照字母表顺序排序;
2.字符串按照字母表顺序排序;
redis 127.0.0.1:6379> lpush l2 snda
(integer) 1
redis 127.0.0.1:6379> lpush l2 tencent
(integer) 2
redis 127.0.0.1:6379> lpush l2 baidu
(integer) 3
redis 127.0.0.1:6379> lpush l2 taobao
(integer) 4
redis 127.0.0.1:6379> sort l2 alpha
1) “baidu”
2) “snda”
3) “taobao”
4) “tencent”
redis 127.0.0.1:6379> sort l2 desc alpha
1) “tencent”
2) “taobao”
3) “snda”
4) “baidu”
redis 127.0.0.1:6379> sort l2
(error) ERR One or more scores can’t be converted into double
——————————— sort key [ASC|DESC] [ALPHA] ———————————
——————————— [LIMIT offset count] ———————————
获得l1集合中第二个字符开始的后两个值;
redis 127.0.0.1:6379> sort l1
1) “3”
2) “9”
3) “12”
4) “22”
redis 127.0.0.1:6379> sort l1 limit 1 2
1) “9”
2) “12”
redis 127.0.0.1:6379> sort l1 limit 1 2 desc
1) “12”
2) “9”
——————————— [LIMIT offset count] ———————————
——————————— [BY nosort] ———————————
li列表插入的时候是按照12, 3, 22, 9的顺序插入的,但是实际的物理顺序是反序的,即后插入的元素在前面;
redis 127.0.0.1:6379> sort l1 by nosort
1) “9”
2) “22”
3) “3”
4) “12”
——————————— [BY nosort] ———————————
——————————— [BY pattern] ———————————
redis 127.0.0.1:6379> sort l1 by nosort
1) “9”
2) “22”
3) “3”
4) “12”
redis 127.0.0.1:6379> set weight_3 1
OK
redis 127.0.0.1:6379> set weight_12 2
OK
redis 127.0.0.1:6379> set weight_22 3
OK
redis 127.0.0.1:6379> set weight_9 4
OK
redis 127.0.0.1:6379> sort l1 by weight_*
1) “3”
2) “12”
3) “22”
4) “9”
redis 127.0.0.1:6379> sort l1 by weight_* desc
1) “9”
2) “22”
3) “12”
4) “3”
redis 127.0.0.1:6379> set weight_22 5
OK
redis 127.0.0.1:6379> sort l1 by weight_*
1) “3”
2) “12”
3) “9”
4) “22”
——————————— [BY pattern] ———————————
——————————— [GET pattern …] ———————————
— 1.返回pattern的值,按照pattern的顺序;
redis 127.0.0.1:6379> sort l1 by weight_*  get weight_*
1) “1”
2) “2”
3) “4”
4) “5”
— 2.通过#(#特殊符号引用的是原始集合)返回原来列表中的值;
redis 127.0.0.1:6379> sort l1 by weight_* get weight_* get #
1) “1”
2) “3”
3) “2”
4) “12”
5) “4”
6) “9”
7) “5”
8) “22”
— 3.引用hash类型字段的话需要使用->符号,当值不存在就返回nil;
redis 127.0.0.1:6379> hset h_3 id 1
(integer) 1
redis 127.0.0.1:6379> hset h_22 id 2
(integer) 1
redis 127.0.0.1:6379> hset h_9 id 3
(integer) 1
redis 127.0.0.1:6379> hset h_10 id 4
(integer) 1
redis 127.0.0.1:6379> sort l1 get h_*->id
1) “1”
2) “3”
3) (nil)
4) “2”
——————————— [GET pattern …] ———————————
——————————— [STORE destination] ———————————
把排序的结果保存在一个list中;
redis 127.0.0.1:6379> sort l1
1) “3”
2) “9”
3) “12”
4) “22”
redis 127.0.0.1:6379> sort l1 limit 1 2 store sl1
(integer) 2
redis 127.0.0.1:6379> type sl1
list
redis 127.0.0.1:6379> lrange sl1 0 -1
1) “9”
2) “12”
——————————— [STORE destination] ———————————
——————————— 实际使用的场景及例子 ———————————
— 1.kobe的队友列表,存放队友的号码uid;
redis 127.0.0.1:6379> sadd kobe:team:list 10
(integer) 1
redis 127.0.0.1:6379> sadd kobe:team:list 12
(integer) 1
redis 127.0.0.1:6379> sadd kobe:team:list 15
(integer) 1
redis 127.0.0.1:6379> sadd kobe:team:list 16
(integer) 1
— 2.球员的排序规则,存放球员的得分;
redis 127.0.0.1:6379> set uid:sort:10 1000
OK
redis 127.0.0.1:6379> set uid:sort:12 2000
OK
redis 127.0.0.1:6379> set uid:sort:15 300
OK
redis 127.0.0.1:6379> set uid:sort:16 2500
OK
— 3.队友的信息;
redis 127.0.0.1:6379> set uid:10 “{‘uid’:10,’name’:’Steve Nash’}”
OK
redis 127.0.0.1:6379> set uid:12 “{‘uid’:12,’name’:’Dwight Howard’}”
OK
redis 127.0.0.1:6379> set uid:15 “{‘uid’:15,’name’:’Ron Artest’}”
OK
redis 127.0.0.1:6379> set uid:16 “{‘uid’:16,’name’:’Pau Gasol’}”
OK
— 4.按照得分对球员排序;
redis 127.0.0.1:6379> sort kobe:team:list by uid:sort:* get uid:*
1) “{‘uid’:15,’name’:’Ron Artest’}”
2) “{‘uid’:10,’name’:’Steve Nash’}”
3) “{‘uid’:12,’name’:’Dwight Howard’}”
4) “{‘uid’:16,’name’:’Pau Gasol’}”
redis 127.0.0.1:6379> sort kobe:team:list by uid:sort:* get uid:* get uid:sort:*
1) “{‘uid’:15,’name’:’Ron Artest’}”
2) “300”
3) “{‘uid’:10,’name’:’Steve Nash’}”
4) “1000”
5) “{‘uid’:12,’name’:’Dwight Howard’}”
6) “2000”
7) “{‘uid’:16,’name’:’Pau Gasol’}”
8) “2500”
——————————— 实际使用的场景及例子 ———————————
标签: ,
目前还没有任何评论.