目錄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命令時應該注意如下幾點: