Redis對象——集合(Set)


最新:Redis內存——三個重要的緩沖區

最新:Redis內存——內存消耗(內存都去哪了?)

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

最新:Redis持久化——AOF日志

更多文章...
集合類型 (Set) 是一個無序並唯一的鍵值集合。它的存儲順序不會按照插入的先后順序進行存儲。

集合類型和列表類型的區別如下:

  • 列表可以存儲重復元素,集合只能存儲非重復元素;
  • 列表是按照元素的先后順序存儲元素的,而集合則是無序方式存儲元素的。

一個集合最多可以存儲232-1個元素。Redis除了支持集合內的增刪改查,同時還支持多個集合取交集、並集、差集,合理地使用好集合類型,能在實際開發中解決很多實際問題。

一、內部實現

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

  • intset(整數集合):當集合中的元素都是整數且元素個數小於set-maxintset-entries配置(默認512個)時,Redis會選用intset來作為集合的內部實現,從而減少內存的使用。

  • hashtable(哈希表):當集合類型無法滿足intset的條件時,Redis會使用hashtable作為集合的內部實現。

有關intset和hashtable這兩種redis底層數據結構的具體實現可以參考我的另外兩篇文章。

Redis數據結構——整數集合

Redis數據結構——字典

二、常用命令

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

命令 說明 時間復雜度
SADD key member [member ...] 添加一個或者多個元素到集合(set)里 O(N)
SCARD key 獲取集合里面的元素數量 O(1)
SDIFF key [key ...] 獲得隊列不存在的元素 O(N)
SDIFFSTORE destination key [key ...] 獲得隊列不存在的元素,並存儲在一個關鍵的結果集 O(N)
SINTER key [key ...] 獲得兩個集合的交集 O(N*M)
SINTERSTORE destination key [key ...] 獲得兩個集合的交集,並存儲在一個關鍵的結果集 O(N*M)
SISMEMBER key member 確定一個給定的值是一個集合的成員 O(1)
SMEMBERS key 獲取集合里面的所有元素 O(N)
SMOVE source destination member 移動集合里面的一個元素到另一個集合 O(1)
SPOP key [count] 刪除並獲取一個集合里面的元素 O(1)
SRANDMEMBER key [count] 從集合里面隨機獲取一個元素
SREM key member [member ...] 從集合里刪除一個或多個元素 O(N)
SUNION key [key ...] 添加多個set元素 O(N)
SUNIONSTORE destination key [key ...] 合並set元素,並將結果存入新的set里面 O(N)
SSCAN key cursor [MATCH pattern] [COUNT count] 迭代set里面的元素 O(1)

三、使用場景

通過上文,我們可以知道集合的主要幾個特性,無序、不可重復、支持並交差等操作。因此集合類型比較適合用來數據去重和保障數據的唯一性,還可以用來統計多個集合的交集、錯集和並集等,當我們存儲的數據是無序並且需要去重的情況下,比較適合使用集合類型進行存儲。

3.1 標簽系統

集合類型比較典型的使用場景是標簽(tag)。

  1. 給用戶添加標簽。

    sadd user:1:tags tag1 tag2 tag5
    sadd user:2:tags tag2 tag3 tag5
    ...
    sadd user:k:tags tag1 tag2 tag4
    ...
    
  2. 給標簽添加用戶

    sadd tag1:users user:1 user:3
    sadd tag2:users user:1 user:2 user:3
    ...
    sadd tagk:users user:1 user:2
    ...
    
  3. 使用sinter命令,可以來計算用戶共同感興趣的標簽

    sinter user:1:tags user:2:tags
    

這種標簽系統在電商系統、社交系統、視頻網站,圖書網站,旅游網站等都有着廣泛的應用。例如一個用戶可能對娛樂、體育比較感興趣,另一個用戶可能對歷史、新聞比較感興趣,這些興趣點就是標簽。有了這些數據就可以得到喜歡同一個標簽的人,以及用戶的共同喜好的標簽,這些數據對於用戶體驗以及增強用戶黏度比較重要。例如一個社交系統可以根據用戶的標簽進行好友的推薦,已經用戶感興趣的新聞的推薦等,一個電子商務的網站會對不同標簽的用戶做不同類型的推薦,比如對數碼產品比較感興趣的人,在各個頁面或者通過郵件的形式給他們推薦最新的數碼產品,通常會為網站帶來更多的利益。

3.2 抽獎系統

Redis集合的 SPOP(隨機移除並返回集合中一個或多個元素)SRANDMEMBER(隨機返回集合中一個或多個元素) 命令可以幫助我們實現一個抽獎系統

如果允許重復中獎,可以使用SRANDMEMBER 命令

//添加抽獎名單
127.0.0.1:6379> SADD lucky:1 Tom
(integer) 1
127.0.0.1:6379> SADD lucky:1 Jerry
(integer) 1
127.0.0.1:6379> SADD lucky:1 John
(integer) 1
127.0.0.1:6379> SADD lucky:1 Marry
(integer) 1
127.0.0.1:6379> SADD lucky:1 Sean
(integer) 1
127.0.0.1:6379> SADD lucky:1 Lindy
(integer) 1
127.0.0.1:6379> SADD lucky:1 Echo
(integer) 1

//抽取三等獎3個
127.0.0.1:6379> SRANDMEMBER lucky:1 3
1) "John"
2) "Echo"
3) "Lindy"
//抽取二等獎2個
127.0.0.1:6379> SRANDMEMBER lucky:1 2
1) "Sean"
2) "Lindy"
//抽取一等獎1個
127.0.0.1:6379> SRANDMEMBER lucky:1 1
1) "Tom"    

如果不允許重復中獎,可以使用 SPOP 命令

//添加抽獎名單
127.0.0.1:6379> SADD lucky:1 Tom
(integer) 1
127.0.0.1:6379> SADD lucky:1 Jerry
(integer) 1
127.0.0.1:6379> SADD lucky:1 John
(integer) 1
127.0.0.1:6379> SADD lucky:1 Marry
(integer) 1
127.0.0.1:6379> SADD lucky:1 Sean
(integer) 1
127.0.0.1:6379> SADD lucky:1 Lindy
(integer) 1
127.0.0.1:6379> SADD lucky:1 Echo
(integer) 1

//抽取三等獎3個
127.0.0.1:6379> SPOP lucky:1 3
1) "John"
2) "Echo"
3) "Lindy"
//抽取二等獎2個
127.0.0.1:6379> SPOP lucky:1 2
1) "Sean"
2) "Marry"
//抽取一等獎1個
127.0.0.1:6379> SPOP lucky:1 1
1) "Tom"   

注意:

Redis 2.6版本開始SRANDMEMBER命令支持Count參數。

Redis 3.2版本開始SRANDMEMBER命令支持Count參數。

其余低版本一次只能獲取一個隨機元素。

小結

本篇文章我們總結了Redis 集合對象的內部實現、常用命令以及常用的一些場景,那么大家在項目中對Redis集合對象的使用都有哪些場景呢,歡迎在評論區給我留言和分享,我會第一時間反饋!我們共同學習與進步!

系列文章:

最新:Redis內存——三個重要的緩沖區

最新:Redis內存——內存消耗(內存都去哪了?)

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

最新:Redis持久化——AOF日志

Redis持久化——內存快照(RDB)

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

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

Redis對象——集合(Set)

Redis對象——列表(List)

Redis對象——哈希(Hash)

Redis數據結構——quicklist

Redis對象——字符串

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

Redis數據結構——壓縮列表

Redis數據結構——整數集合

Redis數據結構——跳躍表

Redis數據結構——字典

Redis數據結構——鏈表

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

-----END-----

關注下方公眾號,回復“Redis”,可得Redis相關學習資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM