redis 有sort set資料結構,但僅僅只能安裝score排序,
我想實現不僅按照score排序,還需要按照其他欄位排序,
比如按照熱度,發布時間排序,應該怎樣實現?
就是類似實現mysql中的 select * from topic order by hot desc ,createtime desc這種排序
環境: mysql(資料庫) + redis(緩衝)
情境: 論壇貼文清單
帶分頁需要按照時間/熱度/等排序需要在列表就顯示標題跟內容
並發量: 峰值可能會到幾萬,但期間可能也就一天,並且讀寫都可能比較頻繁
回複內容:
redis 有sort set資料結構,但僅僅只能安裝score排序,
我想實現不僅按照score排序,還需要按照其他欄位排序,
比如按照熱度,發布時間排序,應該怎樣實現?
就是類似實現mysql中的 select * from topic order by hot desc ,createtime desc這種排序
環境: mysql(資料庫) + redis(緩衝)
情境: 論壇貼文清單
帶分頁需要按照時間/熱度/等排序需要在列表就顯示標題跟內容
並發量: 峰值可能會到幾萬,但期間可能也就一天,並且讀寫都可能比較頻繁
redis本身 機制 並不是熱衷於 比較複雜的排序,
不過 可以 先做好排序工作,然後存放在 redis列表中,將列表裁剪為指定長度,比如 1000條,Redis只需要儲存最新的1000條,每次需要擷取最新文章或者評論的專案範圍時,再查庫擷取放到緩衝中
可不可以多個有序集,每個有序集實現一種排序
每天淩晨跑一個指令碼讓排序好的資料存進redis
每個東西都有他擅長的,要相互結合使用
可以把熱度$a,發布時間$b做一個比重當做score,熱度佔30%
zadd $a*0.3 $user_id zadd $b*0.7 $user_id
,然後zrangebyscore
按每種排序方式都排一次序,並將排序結果緩衝起來,將排序這種複雜的操作交給DB,或者應用程式,而redis只負責緩衝,不負責商務邏輯。畢竟redis只是一個簡單的緩衝,不能完成像DB那樣負責的操作。
Redis用一個Sorted Set解決按兩個欄位排序的問題,也就是按照熱度+時間作為排序欄位,關鍵在於怎麼拼接score的問題。這種特點的情境,解決方案是組裝一個浮點數,整數部分是熱度的值,小數部分是時間。這裡要注意的是,redis裡面精度應該是小數6位,所以不能把整個日期作為小數部分。例如有這樣一組資料:
| 熱度 | 時間 |
| 2 | 2016-03-31 13:41:01 |
| 5 | 2016-03-31 13:41:01 |
| 2 | 2016-03-31 13:42:01 |
| 1 | 2016-03-31 13:41:01 |
那麼score的值可以組裝成:
| 熱度 | 時間 | score
| 2 | 2016-03-31 13:41:01 | 2.134101
| 5 | 2016-03-31 13:41:01 | 5.134101
| 2 | 2016-03-31 13:42:01 | 2.134201
| 1 | 2016-03-31 13:41:01 | 1.134101
這樣的局限性是每個zset只能存一天的資料