1. 程式人生 > 其它 >用Redis命令還能做抽獎?

用Redis命令還能做抽獎?

技術標籤:Redis

各位小夥伴們,2020還有最後兩週就要結束了,很多公司陸陸續續也都開始了年會的準備工作。而年會上,大家最期待的節目,無疑就是抽獎了。

有一天,領導告訴你 “小胖兒,公司馬上開年會了,你給我們寫個抽獎程式吧”。隨後,你默默地打開了Eclipse,開始寫Math.random()。

今天,風哥告訴你,抽獎這事兒,其實不用這麼麻煩,可以考慮使用Redis的set集合。


我們都知道,set的兩大特點,去重和無序。同樣,Redis的set也滿足這兩個特點。

先來看看Redis的set提供給我們哪些用法(可以發現,set相關的命令大多以s開頭)。

127.0.0.1:6379> help @set
  SADD key member [member ...]
  summary: Add one or more members to a set
  since: 1.0.0

  SCARD key
  summary: Get the number of members in a set
  since: 1.0.0

  SDIFF key [key ...]
  summary: Subtract multiple sets
  since: 1.0.0

  SDIFFSTORE destination key [key ...]
  summary: Subtract multiple sets and store the resulting set in a key
  since: 1.0.0

  SINTER key [key ...]
  summary: Intersect multiple sets
  since: 1.0.0

  SINTERSTORE destination key [key ...]
  summary: Intersect multiple sets and store the resulting set in a key
  since: 1.0.0

  SISMEMBER key member
  summary: Determine if a given value is a member of a set
  since: 1.0.0

  SMEMBERS key
  summary: Get all the members in a set
  since: 1.0.0

  SMOVE source destination member
  summary: Move a member from one set to another
  since: 1.0.0

  SPOP key [count]
  summary: Remove and return one or multiple random members from a set
  since: 1.0.0

  SRANDMEMBER key [count]
  summary: Get one or multiple random members from a set
  since: 1.0.0

  SREM key member [member ...]
  summary: Remove one or more members from a set
  since: 1.0.0

  SSCAN key cursor [MATCH pattern] [COUNT count]
  summary: Incrementally iterate Set elements
  since: 2.8.0

  SUNION key [key ...]
  summary: Add multiple sets
  since: 1.0.0

  SUNIONSTORE destination key [key ...]
  summary: Add multiple sets and store the resulting set in a key
  since: 1.0.0

我們挑幾個常用的看一下。

127.0.0.1:6379>SADDk1a ab bcd//在名為k1的集合中新增abcd四個元素
(integer) 4
127.0.0.1:6379>SADDk2bcde
(integer) 4
127.0.0.1:6379>SCARDk1//列出集合的大小
(integer) 4
127.0.0.1:6379>SMEMBERSk1//列出集合中所有元素,可以看出“去重且亂序”的
1) "c"
2) "a"
3) "d"
4) "b"
127.0.0.1:6379>SISMEMBERk1a//集合k1是否包含a
(integer) 1
127.0.0.1:6379> SISMEMBER k1 aa
(integer) 0
127.0.0.1:6379>sdiffk1k2//集合k1和k2的差異,k1,k2是有順序的(k1-k2)
1) "a"
127.0.0.1:6379> sdiff k2 k1
1) "e"
127.0.0.1:6379> SUNION k1 k2 // 並集
1) "a"
2) "d"
3) "b"
4) "c"
5) "e"
127.0.0.1:6379> SINTER k1 k2 //交集
1) "c"
2) "d"
3) "b"
127.0.0.1:6379>SRANDMEMBERk1//從集合中隨機取出(get)一個元素
"c"
127.0.0.1:6379> SRANDMEMBER k1
"b"
127.0.0.1:6379>SRANDMEMBERk13//從集合中隨機(這不廢話嗎,反正set也是無序的)取出3個元素
1) "c"
2) "d"
3) "b"
127.0.0.1:6379> SRANDMEMBER k1 3
1) "a"
2) "d"
3) "b"
127.0.0.1:6379>SPOP k13//從集合中隨機取出(remove)3個元素
1) "d"
2) "a"
3) "b"
127.0.0.1:6379> SPOP k1 2
1) "c"

​​​​​看到這你可能已經發現了,抽獎這事兒,用 SRANDMEMBER 或者 SPOP 就能搞定。

1. 獎品數>抽獎人數

假設3個人的公司,準備了5份獎品,即可以重複中獎。

127.0.0.1:6379> sadd lotteryList tom jerry tony
(integer) 3
127.0.0.1:6379>SRANDMEMBERlotteryList-5//如果為負數,會首先滿足返回元素個數,可能會有重複
1) "tom"
2) "jerry"
3) "tony"
4) "jerry"
5) "jerry"

2. 獎品數<抽獎人數

127.0.0.1:6379> sadd lottoryList tom jerry jack tony lucy lily poly kevin
(integer) 8
127.0.0.1:6379>spoplottoryList3//三等獎
1) "jerry"
2) "jack"
3) "lily"
127.0.0.1:6379>spoplottoryList2//二等獎
1) "kevin"
2) "poly"
127.0.0.1:6379>spoplottoryList1//一等獎
1) "tony"


總結

我們稍微總結一下,類似抽獎這種簡單隨機場景,可以根據實際情況,考慮另一種思路,即使用Redis的SRANDMEMBER或者spop來實現。

好了,本次分享就是這樣,我們下次講 sorted_set,希望你能有收穫。