Redis對象——有序集合(ZSet)

系列文章

最新:Redis持久化——如何選擇合適的持久化方式html

最新:Redis持久化——AOF日誌redis

最新:Redis持久化——內存快照(RDB)數據結構

一文回顧Redis五大對象(數據類型)運維

Redis對象——有序集合(ZSet)ide

Redis對象——集合(Set)學習

Redis對象——列表(List)網站

Redis對象——哈希(Hash)ui

Redis數據結構——quicklist設計

Redis對象——字符串日誌

Redis對象——Redis對象系統簡介

Redis數據結構——壓縮列表

Redis數據結構——整數集合

Redis數據結構——跳躍表

Redis數據結構——字典

Redis數據結構——鏈表

Redis數據結構——簡單動態字符串SDS

有序集合類型 (Sorted Set或ZSet) 相比於集合類型多了一個排序屬性 score(分值),對於有序集合 ZSet 來講,每一個存儲元素至關於有兩個值組成的,一個是有序結合的元素值,一個是排序值。有序集合保留了集合不能有重複成員的特性(分值能夠重複),但不一樣的是,有序集合中的元素能夠排序。

1、內部實現

有序集合是由 ziplist (壓縮列表)skiplist (跳躍表) 組成的。

當數據比較少時,有序集合使用的是 ziplist 存儲的,有序集合使用 ziplist 格式存儲必須知足如下兩個條件:

  • 有序集合保存的元素個數要小於 128 個;
  • 有序集合保存的全部元素成員的長度都必須小於 64 字節。

若是不能知足以上兩個條件中的任意一個,有序集合將會使用 skiplist 結構進行存儲。

有關ziplist 和skiplist 這兩種redis底層數據結構的具體實現能夠參考個人另外兩篇文章。

Redis數據結構——壓縮列表

Redis數據結構——跳躍表

2、經常使用命令

Redis列表對象經常使用命令以下表(點擊命令可查看命令詳細說明)。

命令 說明 時間複雜度
BZPOPMAX key [key ...] timeout 從一個或多個排序集中刪除並返回得分最高的成員,或阻塞,直到其中一個可用爲止 O(log(N))
BZPOPMIN key [key ...] timeout 從一個或多個排序集中刪除並返回得分最低的成員,或阻塞,直到其中一個可用爲止 O(log(N))
ZADD key [NXXX] [CH] [INCR] score member [score member ...] 添加到有序set的一個或多個成員,或更新的分數,若是它已經存在 O(log(N))
ZCARD key 獲取一個排序的集合中的成員數量 O(1)
ZCOUNT key min max 返回分數範圍內的成員數量 O(log(N))
ZINCRBY key increment member 增量的一名成員在排序設置的評分 O(log(N))
ZINTERSTORE 相交多個排序集,致使排序的設置存儲在一個新的關鍵 O(NK)+O(Mlog(M))
ZLEXCOUNT key min max 返回成員之間的成員數量 O(log(N))
ZPOPMAX key [count] 刪除並返回排序集中得分最高的成員 O(log(N)*M)
ZPOPMIN key [count] 刪除並返回排序集中得分最低的成員 O(log(N)*M)
ZRANGE key start stop [WITHSCORES] 根據指定的index返回,返回sorted set的成員列表 O(log(N)+M)
ZRANGEBYLEX key min max [LIMIT offset count] 返回指定成員區間內的成員,按字典正序排列, 分數必須相同。 O(log(N)+M)
ZREVRANGEBYLEX key max min [LIMIT offset count] 返回指定成員區間內的成員,按字典倒序排列, 分數必須相同 O(log(N)+M)
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 返回有序集合中指定分數區間內的成員,分數由低到高排序。 O(log(N)+M)
ZRANK key member 肯定在排序集合成員的索引 O(log(N))
ZREM key member [member ...] 從排序的集合中刪除一個或多個成員 O(M*log(N))
ZREMRANGEBYLEX key min max 刪除名稱按字典由低到高排序成員之間全部成員。 O(log(N)+M)
ZREMRANGEBYRANK key start stop 在排序設置的全部成員在給定的索引中刪除 O(log(N)+M)
ZREMRANGEBYSCORE key min max 刪除一個排序的設置在給定的分數全部成員 O(log(N)+M)
ZREVRANGE key start stop [WITHSCORES] 在排序的設置返回的成員範圍,經過索引,下令從分數高到低 O(log(N)+M)
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 返回有序集合中指定分數區間內的成員,分數由高到低排序。 O(log(N)+M)
ZREVRANK key member 肯定指數在排序集的成員,下令從分數高到低 O(log(N))
ZSCORE key member 獲取成員在排序設置相關的比分 O(1)
ZUNIONSTORE 添加多個排序集和致使排序的設置存儲在一個新的關鍵 O(N)+O(M log(M))
ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代sorted sets裏面的元素 O(1)

3、使用場景

3.1 排行榜系統

有序集合比較典型的使用場景就是排行榜系統。例如學生成績的排名。某視頻(博客等)網站的用戶點贊、播放排名、電商系統中商品的銷量排名等。咱們以博客點贊爲例。

  1. 添加用戶贊數

例如小編Tom發表了一篇博文,而且得到了10個贊。

zadd user:ranking arcticle1 10
  1. 取消用戶贊數

這個時候有一個讀者又以爲Tom寫的很差,又取消了贊,此時須要將文章的贊數從榜單中減去1,能夠使用zincrby。

zincrby user:ranking arcticle1 -1
  1. 查看某篇文章的贊數
ZSCORE user:ranking arcticle1
  1. 展現獲取贊數最多的十篇文章

此功能使用zrevrange命令實現:

zrevrangebyrank user:ranking  0 9

3.2 電話號碼(姓名)排序

使用有序集合的ZRANGEBYLEX(點擊可查看該命令詳細說明)ZREVRANGEBYLEX能夠幫助咱們實現電話號碼或姓名的排序,咱們以ZRANGEBYLEX爲例
注意:不要在分數不一致的SortSet集合中去使用 ZRANGEBYLEX和 ZREVRANGEBYLEX 指令,由於獲取的結果會不許確。

  1. 電話號碼排序

咱們能夠將電話號碼存儲到SortSet中,而後根據須要來獲取號段:

redis> zadd phone 0 13100111100 0 13110114300 0 13132110901 
(integer) 3
redis> zadd phone 0 13200111100 0 13210414300 0 13252110901 
(integer) 3
redis> zadd phone 0 13300111100 0 13310414300 0 13352110901 
(integer) 3

獲取全部號碼:

redis> ZRANGEBYLEX phone - +
1) "13100111100"
2) "13110114300"
3) "13132110901"
4) "13200111100"
5) "13210414300"
6) "13252110901"
7) "13300111100"
8) "13310414300"
9) "13352110901"

獲取132號段:

redis> ZRANGEBYLEX phone [132 (133
1) "13200111100"
2) "13210414300"
3) "13252110901"

獲取13二、133號段:

redis> ZRANGEBYLEX phone [132 (134
1) "13200111100"
2) "13210414300"
3) "13252110901"
4) "13300111100"
5) "13310414300"
6) "13352110901"
  1. 姓名排序

將名稱存儲到SortSet中:

redis> zadd names 0 Toumas 0 Jake 0 Bluetuo 0 Gaodeng 0 Aimini 0 Aidehua 
(integer) 6

獲取全部人的名字:

redis> ZRANGEBYLEX names - +
1) "Aidehua"
2) "Aimini"
3) "Bluetuo"
4) "Gaodeng"
5) "Jake"
6) "Toumas"

獲取名字中大寫字母A開頭的全部人:

redis> ZRANGEBYLEX names [A (B
1) "Aidehua"
2) "Aimini"

獲取名字中大寫字母C到Z的全部人:

redis> ZRANGEBYLEX names [C [Z
1) "Gaodeng"
2) "Jake"
3) "Toumas"

小結

本篇文章咱們總結了Redis 有序集合對象的內部實現、經常使用命令以及經常使用的一些場景,有序集合提供了獲取指定分數和元素範圍查詢、計算成員排名等功能,合理的利用有序集合,能幫助咱們在實際開發中解決不少問題。那麼你們在項目中對Redis有序集合對象的使用都有哪些場景呢,歡迎在評論區給我留言和分享,我會第一時間反饋!咱們共同窗習與進步!

參考

《Redis設計與實現》

《Redis開發與運維》

《Redis官方文檔》

-----END-----

關注下方公衆號,回覆「Redis」,可得Redis相關學習資料

相關文章
相關標籤/搜索