Redis:12---有序集合對象

一、有序集合對象概述

  • 它保留了集合不能有重復成員的特性, 但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下標作為排序依據不同的是,它給每個元素設置一個分數(score)作為排序的依據

  • 如下圖所示,該有序集合包含kris、mike、frank、tim、martin、tom, 它們的分數分別是1、91、200、220、250、251,有序集合提供了獲取指定 分數和元素范圍查詢、計算成員排名等功能,合理的利用有序集合,能幫助我們在實際開發中解決很多問題

? ? ? ? ??? ??? ?

  • 特點:

    • 有序集合中的鍵被稱為“成員”,成員的值成為“分值”,分值必須為浮點數

    • 散列只能通過鍵訪問元素。但是有序集合既可以通過鍵訪問元素,也可以根據分值以及分值的排列順序來訪問元素的結構

    • 和散列一樣,都是用于存儲鍵值對,鍵值不允許重復

    • 與散列的不同:

  • 下圖列出了列表、集合和有序集合三者的異同點:

二、命令

命令

  • zadd:添加成員。返回結果代表成功添加成員的個數

  • 有關zadd命令有兩點需要注意:

    • nx:member必須不存在,才可以設置成功,用于添加

    • xx:member必須存在,才可以設置成功,用于更新

    • ch:返回此次操作后,有序集合元素和分數發生變化的個數

    • incr:對score做增加,相當于后面介紹的zincrby

    • ?Redis3.2為zadd命令添加了nx、xx、ch、incr四個選項:

    • 有序集合相比集合提供了排序字段,但是也產生了代價,zadd的時間復雜度為O(log(n)),sadd的時間復雜度為O(1)

zadd key score member [score member ...]

?

  • zcard:計算成員個數。時間復雜度為O(1)

zcard key

  • zscore:計算某個成員的分數。如果成員不存在則返回nil

zscore key member

?

  • zrank、zrevrank:計算成員排名。zrank是從分數從低到高返回排名,zrevrank反之。排名從0開始

zrank key member
zrevrank key member

  • zrem:刪除成員。返回結果為成功刪除的個數

zrem key member [member ...]

?

  • zincrby:增加成員的分數

zincrby key increment member

  • zrange、zrevrange:返回指定排名范圍的成員

    • 有序集合是按照分值排名的,zrange是從低到高返回,zrevrange反之

    • 如果加上withscores選項,同時會返 回成員的分數

zrange key start end [withscores]
zrevrange key start end [withscores]

  • zrangebyscore、zrevrangebyscore:返回指定分數范圍的成員

    • 其中zrangebyscore按照分數從低到高返回,zrevrangebyscore反之

    • [limit offset count]選項可以限制輸出的起始位置和個數

    • 同時min和max還支持開區間(小括號)和閉區間(中括號),-inf和 +inf分別代表無限小和無限大

zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]

?

  • zcount:返回指定分數范圍成員個數

zcount key min max

?

  • zremrangebyrank:刪除指定排名內的升序元素

zremrangebyrank key start end

?

  • zremrangebyscore:刪除指定分數范圍的成員

zremrangebyscore key min max

?

集合間的操作

  • 將下圖的兩個有序集合導入到Redis中:

  • zinterstore:交集。參數如下:

    • destination:交集計算結果保存到這個鍵

    • numkeys:需要做交集計算鍵的個數

    • key[key...]:需要做交集計算的鍵

    • weights weight[weight...]:每個鍵的權重,在做交集計算時,每個鍵中 的每個member會將自己分數乘以這個權重,每個鍵的權重默認是1

    • aggregate sum|min|max:計算成員交集后,分值可以按照sum(和)、 min(最小值)、max(最大值)做匯總,默認值是sum

zinterstore destination numkeys key [key ...] [weights weight [weight ...]]
[aggregate sum|min|max]
  • 下面操作對user:ranking:1和user:ranking:2做交集,weights和 aggregate使用了默認配置,可以看到目標鍵user:ranking:1_inter_2對分值 做了sum操作:

  • ?如果想讓user:ranking:2的權重變為0.5,并且聚合效果使用max,可以 執行如下操作:

  • zunionstore:并集。該命令的所有參數和zinterstore是一致的,只不過是做并集計算

zunionstore destination numkeys key [key ...] [weights weight [weight ...]]
[aggregate sum|min|max]
  • 例如 下面操作是計算user:ranking:1和user:ranking:2的并集,weights和 aggregate使用了默認配置,可以看到目標鍵user:ranking:1_union_2對分值 做了sum操作:?

  • 下圖給出了有序集合命令的復雜度:

命令時間復雜度
zadd? keyscoremember[scoremember...]O(kXlo()),k是添加成員的個數,”是當前有序
集合成員個數
zcard key0(1)
zscore key member0(1).
zrank key member
arevrank key member
0(og(),”是當前有序集合成員個數
rem key member[member...10(k*1og()),k是刪除成員的個數,"是當前有序集
合成員個數
zincrby key increment memberO(log(m)),”是當前有序集合成員個數
zrange key? start? end[withscores]
zrevrange key? start end[withscores]
O(log(m)+k),k是要獲取的成員個數,η是當前有
序集合成員個數
zrangebyscore key? min? max[withscores]
zrevrangebyscore key max min[withscores]
0(log(m)+k),k是要獲取的成員個數,η是當前有
序集合成員個數
zcount0(log(n)),"是當前有序集合成員個數
zremrangebyrank key start endO(log(m)+k),k是要刪除的成員個數,”是當前有
序集合成員個數
zremrangebyscore key min maxO(log(n)+k),k是要刪除的成員個數,是當前有
序集合成員個數
zinterstore destinationnum keys key[key...1(n*k)+0O(m*log(m)),”是成員數最小的有序集合成
員個數,k是有序集合的個數,m是結果集中成員個數
zunionstore destinationnum keys key[key...]0()+O(m*log(m)),”是所有有序集合成員個數和,
m是結果集中成員個數

三、內部編碼

  • 有序集合類型的內部編碼有兩種:

    • ziplist(壓縮列表):當有序集合的元素個數小于zset-max-ziplistentries配置(默認128個),同時每個元素的值都小于zset-max-ziplist-value配 置(默認64字節)時,Redis會用ziplist來作為有序集合的內部實現,ziplist 可以有效減少內存的使用

    • skiplist(跳躍表):當ziplist條件不滿足時,有序集合會使用skiplist作 為內部實現,因為此時ziplist的讀寫效率會下降

演示說明

  • 當元素個數較少且每個元素較小時,內部編碼為skiplist:

  • 當元素個數超過128個,內部編碼變為ziplist

  • 當某個元素大于64字節時,內部編碼也會變為skiplist:

四、應用場景

排行榜

  • 有序集合比較典型的使用場景就是排行榜系統。例如游戲里經常要對用戶的副本關卡得分,聲望,戰力,段位等做排行榜,榜單的維度可能是多個方面的:按照等級,最后分數更新時間。本節使用等級這個維度,記錄每天用戶副本星級的排行榜。主要需要實現以下4個功能

  • ①添加玩家星級。例如玩家mike打副本勝利獲得了3顆星,可以使用有序集合的zadd和zincrby功能:

zadd user:ranking mike 3
  • 如果之后再獲得一個星星,可以使用zincrby:

zincrby user:ranking mike 1
  • ②取消用戶星級排行信息。由于各種原因(例如用戶注銷、用戶作弊)需要將用戶刪除,此時需要 將用戶從榜單中刪除掉,可以使用zrem。例如刪除成員tom:

zrem user:ranking mike
  • ③展示獲取前十名用戶。此功能使用zrevrange命令實現:

zrevrangebyrank user:ranking 0 9
  • ④展示用戶信息以及用戶分數。此功能將用戶名作為鍵后綴,將用戶信息保存在哈希類型中,至于用戶的分數和排名可以使用zscore和zrank兩個功能:

hgetall user:info:tom
zscore user:ranking mike
zrank user:ranking mike

時間線

  • 在互聯網上,有很多網站都會根據內容的發布時間來對內容進行排序,比如:

    • 博客系統會按照文章發布時間的先后,把最近發布的文章放在前面,而發布時間較早的文章則放 在后面,這樣訪客在瀏覽博客的時候,就可以先閱讀最新的文章,然后再閱讀較早的文章

    • 新聞網站會按照新聞的發布時間,把最近發生的新聞放在網站的前面,而早前發生的新聞則放在網站的后面,這樣當用戶訪問該網站的時候,就可以第一時間查看到最新的新聞報道

    • 諸如微博和Twitter 這樣的微博客都會把用戶最新發布的消息放在頁面的前面,而稍早之前發布的 消息則放在頁面的后面,這樣用戶就可以通過向后滾動網頁,查看最近一段時間自己關注的人都發表了哪些動態

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/444313.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/444313.shtml
英文地址,請注明出處:http://en.pswp.cn/news/444313.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis:14---常用功能之(Pipeline)

一、Pipeline概述 Redis客戶端執行一條命令分為如下四個過程:1.發送命令2.命令排隊3.命令執行4.返回結果其中1+4稱為Round Trip Time(RTT,往返時間)Pipeline概述 Redis提供了批量操作命令(例如mget、mset等),有效地節約RTT。但大部分命令是不支持批量操作的,例如要執行…

leetcode170. 兩數之和 III - 數據結構設計

設計并實現一個 TwoSum 的類,使該類需要支持 add 和 find 的操作。 add 操作 - 對內部數據結構增加一個數。 find 操作 - 尋找內部數據結構中是否存在一對整數,使得兩數之和與給定的數相等。 示例 1: add(1); add(3); add(5); find(4) -> true fi…

Redis:11---Set對象

集合類型 (Set) 是一個無序并唯一的鍵值集合。它的存儲順序不會按照插入的先后順序進行存儲。 集合類型和列表類型的區別如下: 列表可以存儲重復元素,集合只能存儲非重復元素;列表是按照元素的先后順序存儲元素的,而集合則是無序方式存儲元素的。一、集合對象概述 特點:集…

Oracle中計算兩個時間的時間差:

計算時間差是oracledata數據類型的一個常見問題。oracle支持日期計算,你可以創建諸如“日期1-日期2”這樣的表達式來計算這兩個日期之間的時間差。一旦你發現了時間差異,你可以使用簡單的技巧來以天、小時、分鐘或者秒為單位來計算時間差。為…

Redis:13--常用功能之redis-cli redis-server等命令

Redis提供了redis-cli、redis-server、redis-benchmark等Shell工具。它們 雖然比較簡單,但是麻雀雖小五臟俱全,有時可以很巧妙地解決一些問題一、redis-cli在前面數據庫連接的時候已經redis-cli的-h、-p參數,除了這些參數,還有很多…

Redis:16---常用功能之(慢查詢日志)

一、慢查詢日志介紹 許多存儲系統(例如MySQL)提供慢查詢日志幫助開發和運維人員定位系統存在的慢操作。所謂慢查詢日志就是系統在命令執行前后計算每條命令的執行時間,當超過預設閥值,就將這條命令的相關信息記錄下來,Redis也提供了類似的功能Redis的慢查詢日志功能用于記…

leetcode256. 粉刷房子

假如有一排房子,共 n 個,每個房子可以被粉刷成紅色、藍色或者綠色這三種顏色中的一種,你需要粉刷所有的房子并且使其相鄰的兩個房子顏色不能相同。 當然,因為市場上不同顏色油漆的價格不同,所以房子粉刷成不同顏色的花…

Redis:21---客戶端相關配置篇

一、客戶端相關配置①客戶端的限制maxclientsRedis提供了maxclients參數來限制最大客戶端連接數,一旦連接數超過 maxclients,新的連接將被拒絕maxclients默認值是10000可以通過info clients來查詢當前Redis的連接數:可以通過config set maxcl…

Redis:23---info命令總結

info命令的格式有3種:info:部分Redis系統狀態統計信息info all:全部Redis系統狀態統計信息,一次性打印下面所有p的內容info p:某一塊的系統狀態統計信息。info命令所有的p如下所示模塊名模塊含義 Server服務器信息Clie…

Redis:22---客戶端API:client、monitor)

一、client listclient list命令能列出與Redis服務端相連的所有客戶端連接信息。例如下面代碼是在一個Redis實例上執行client list的結果,其中每一行代表一個客戶端信息:下面將選擇幾個重要的屬性進行說明,其余通過表格的形式進行展示①標識&…

leetcode175. 組合兩個表(SQL)

表1: Person ---------------------- | 列名 | 類型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- PersonId 是上表主鍵 表2: Address ---------------------- | 列名 …

Redis:20---常用功能之(發布與訂閱)

一、發布與訂閱概述Redis提供了基于“發布/訂閱”模式的消息機制,此種模式下,消息發布者和訂閱者不進行直接通信,發布者客戶端向指定的頻道(channel)發布消息,訂閱該頻道的每個客戶端都可以收到該消息。 下…

Redis:19---常用功能之(HyperLogLog)

一、HyperLogLog概述HyperLogLog并不是一種新的數據結構(實際類型為字符串類型),而是一種基數算法,通過HyperLogLog可以利用極小的內存空間完成獨立總數的統計,數據集可以是IP、Email、ID等HyperLogLog提供了3個命令&a…

計算時間差的Oracle函數

Oracle函數可以實現諸多的功能,下面就介紹使用Oracle函數計算時間差的實現方法,如果您對Oracle函數方面感興趣的話,不妨一看。 兩個Date類型字段:START_DATE,END_DATE,計算這兩個日期的時間差(分…

leetcode181. 超過經理收入的員工(SQL)

Employee 表包含所有員工,他們的經理也屬于員工。每個員工都有一個 Id,此外還有一列對應員工的經理的 Id。 ------------------------------ | Id | Name | Salary | ManagerId | ------------------------------ | 1 | Joe | 70000 | 3 |…

UNIX(多線程):01---線程簡介及線程限制

一、線程的概念 典型的UNIX進程可以看成只有一個控制線程:一個進程在同一時刻只做一件事。有了多個控制線程后,在程序設計時可以把進程設計成在同一時刻能夠做不止一件事,每個線程處理各自獨立的任務二、線程的優點 通過為每種事件類型分配單獨的處理線程,可以簡化處理異步…

UNIX(多線程):13---condition_variable、wait、notify_one、notify_all

條件變量std::condition_variable、wait()、notify_one() 線程A: 等待一個條件滿足線程B: 專門往消息隊列中放入消息(數據),達到一定條件,通知處于等待中的線程A。std::condition_variable實際上是一個類,是一個和條件相關的一個類,說白了就是等待一個條件達成。這個類是…

leetcode176. 第二高的薪水(SQL)

編寫一個 SQL 查詢,獲取 Employee 表中第二高的薪水(Salary) 。 ------------ | Id | Salary | ------------ | 1 | 100 | | 2 | 200 | | 3 | 300 | ------------ 例如上述 Employee 表,SQL查詢應該返回 200 作為第二…

UNIX(多線程):17---異步任務提供者(Provider) 介紹

std::promise 類概述 Promise 對象可以保存某一類型 T 的值,該值可被 future 對象讀取(可能在另外一個線程中),因此 promise 也提供了一種線程同步的手段。在 promise 對象構造時可以和一個共享狀態(通常是std::future)相關聯,并可以在相關聯的共享狀態(std::future)上保…

leetcode180. 連續出現的數字(SQL)

編寫一個 SQL 查詢,查找所有至少連續出現三次的數字。 --------- | Id | Num | --------- | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | --------- 例如,給定上面的 Logs 表, 1 是唯一連續…