自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis 中如何根據(jù)兩個(gè)字段排序

存儲(chǔ) 存儲(chǔ)軟件 Redis
Redis 是一個(gè)內(nèi)存型數(shù)據(jù)庫,其最大的作用就是當(dāng)做緩存使用。提供了幾種數(shù)據(jù)類型,方便開發(fā)過程中應(yīng)對(duì)不同的需求場景。

[[379663]]

 Redis 是一個(gè)內(nèi)存型數(shù)據(jù)庫,其最大的作用就是當(dāng)做緩存使用。提供了幾種數(shù)據(jù)類型,方便開發(fā)過程中應(yīng)對(duì)不同的需求場景。

需求是這樣的,有一些需要排序的數(shù)據(jù),按照不止一個(gè)維度進(jìn)行排序,對(duì)應(yīng)到數(shù)據(jù)庫里,就是按照兩個(gè)字段進(jìn)行綜合排序,那在 Redis 中應(yīng)該使用哪種數(shù)據(jù)結(jié)構(gòu)呢?

按單一字段排序

首先我們先把問題簡化一下,按照一個(gè)字段進(jìn)行排序,看看應(yīng)該怎么實(shí)現(xiàn)。

排行榜場景很常見,比如歷史數(shù)據(jù)排行榜、熱度排行榜(微博熱搜、知乎熱榜等、B站熱門等等),根據(jù)播放量進(jìn)行排序,那針對(duì)這樣的場景,使用 Redis 怎么解決呢?

我們首先忽略掉實(shí)時(shí)更新的問題,假設(shè)是昨日榜單,數(shù)據(jù)已經(jīng)確定了的,不會(huì)改變。

解決方案

列表

有人立馬想到用列表方式解決,因?yàn)榱斜肀旧砭褪怯行虻模园寻駟我?Lists 的形式放到 Redis 中,查詢的時(shí)候直接取 列表就好了,什么都不用管了。

這種方案就是把 Redis 純粹當(dāng)做緩存使用,存什么取什么,其他額外的動(dòng)作一概沒有。

但是這種方案的缺陷也在于此,存進(jìn)來的數(shù)據(jù)就已經(jīng)是排序好的數(shù)據(jù),所以,這個(gè)排序邏輯要在外部程序中提前寫好,然后將排序好的數(shù)據(jù)存進(jìn)去。

那如果外部程序不對(duì)榜單進(jìn)行排序,或者說條件不允許的情況怎么辦呢?那列表就沒辦法了。

有序集合 sorted set

sorted set 是在 Sets 的基礎(chǔ)上增加了分?jǐn)?shù)設(shè)置作為排序依據(jù),所以除了具備 Sets 的特性外,還可以進(jìn)行排序。

它提供了一個(gè) score 屬性,正好可以用來做排序依據(jù),對(duì)榜單類的需求完美匹配。

  1. # 按分?jǐn)?shù)從小到大排序 
  2. ZRANGE key start stop [WITHSCORES] 
  3.  
  4. # 按分?jǐn)?shù)從大到小排序 
  5. ZREVRANGE key start stop [WITHSCORES]   

使用 sorted set 就可以降低外部程序的復(fù)雜度了,程序中不用對(duì)榜單進(jìn)行排行了,只需要將符合入榜條件的記錄拿出來,存到 sorted set 中就可以了。

在 sorted set 結(jié)構(gòu)中,就用訪問量當(dāng)做分?jǐn)?shù),查詢的時(shí)候執(zhí)行 ZREVRANGE 命令就可以了。

按兩個(gè)字段排序

現(xiàn)在需求變了一下,排序的維度有所變化,加了一個(gè)維度。還比如說熱度排行榜吧,之前按訪問量排序,現(xiàn)在增加了按照訪問量和評(píng)論量總和排序,反應(yīng)到數(shù)據(jù)庫上是這樣的:

  1. select * from post order by read_count,comment_count desc 

這種情況下怎么做呢?

解決方案

當(dāng)然還可以用列表

仍然還可以用列表實(shí)現(xiàn),邏輯都不變,只要改變外部程序的查詢邏輯就可以了,之前按一個(gè)字段排序,現(xiàn)在按兩個(gè)來。

有序集合 sorted set

我們知道 sorted set 中只有一個(gè) score 屬性,那怎么用這一個(gè)屬性實(shí)現(xiàn)兩個(gè)維度的排序呢?

這就需要在 score 屬性上做文章了,最簡單的實(shí)現(xiàn),可以將訪問量+評(píng)論數(shù)的和作為 score。

但是這樣精度上太細(xì)了,如果訪問量足夠大,比如上百萬的訪問量,那幾千個(gè)評(píng)論數(shù)也就幾乎可以忽略不計(jì)了,最后實(shí)際的排序還是按照訪問量來的。但是在小訪問量上其實(shí)就可以用這種方式。

比如,訪問量有 9000、8500 的兩個(gè)文章,它倆的評(píng)論量分別為 100 和 700,那最后加起來的結(jié)果就是 9100 和 9200,所以,最后的排序結(jié)果實(shí)際上是閱讀量 8500 的排在前面。

如果訪問量過大的話,可以提高評(píng)論的權(quán)重,比如一個(gè)評(píng)論量等于 100或者1000 個(gè)閱讀量。

還可以降低閱讀量的精度,比如以萬、十萬為單位,如果以十萬為精度,那 111萬和 119萬就都按 110萬來算。

實(shí)時(shí)榜單

除了一些歷史數(shù)據(jù)榜單外, 還有很多榜單都是實(shí)時(shí)的,這種情況下就要保證 redis 中的數(shù)據(jù)是實(shí)時(shí)更新的。

那如果是實(shí)時(shí)更新的情況,用列表存儲(chǔ)就不合適了,讀寫 redis 是為了追求高性能,如果還用列表存儲(chǔ)就意味著外部程序要做實(shí)時(shí)的排序、更新 redis 操作,可想而知,那樣外部程序根本無法做到實(shí)時(shí)更新,或者代價(jià)極大。

所以,就要靠 sorted set 來解決了,可以使用 ZINCRBY命令快速更新 sorted 中的元素的分?jǐn)?shù),比如視頻的播放量更新的時(shí)候通過更新 redis 中的值,因?yàn)楦?redis 的速度是非??斓模钥梢詫?shí)現(xiàn)播放量的實(shí)時(shí)更新。

  1. ZINCRBY key increment member 

因?yàn)橐揽康氖?sorted set 中的分?jǐn)?shù)來排序,所以,當(dāng)成員的分?jǐn)?shù)更新了之后,查詢出來的排行信息就是實(shí)時(shí)的榜單了。

本文轉(zhuǎn)載自微信公眾號(hào)「古時(shí)的風(fēng)箏」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系古時(shí)的風(fēng)箏公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 古時(shí)的風(fēng)箏
相關(guān)推薦

2022-08-14 23:04:54

React前端框架

2022-07-09 20:35:23

數(shù)字化企業(yè)轉(zhuǎn)型

2017-06-14 13:42:00

字典數(shù)據(jù)社交

2011-09-01 21:41:42

SQL Server把字符分割成兩個(gè)字符串

2022-04-01 11:39:32

互聯(lián)網(wǎng)裁員紅利

2013-04-23 09:31:52

SQL Server

2023-03-31 07:31:28

SliceGolang

2011-08-29 18:17:58

Ubuntu

2022-06-27 07:50:16

鏈表節(jié)點(diǎn)測試

2010-04-08 17:40:02

Oracle 多表關(guān)聯(lián)

2022-06-27 08:07:13

Go語言互斥鎖

2014-02-14 18:17:12

文雅科SVF

2009-06-18 14:22:06

Hibernate多對(duì)Hibernate

2020-04-17 10:13:51

Python開發(fā)工具

2020-08-14 08:13:49

列表差異編程

2019-08-28 10:00:34

Python測試工具命令

2020-08-18 08:22:46

歸并排序

2023-05-05 10:45:39

聯(lián)合索引數(shù)據(jù)

2024-05-13 08:35:27

PyObjectPython對(duì)象

2010-03-31 14:20:23

Oracle內(nèi)存結(jié)構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)