用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> SADD k1 a a b b c d //在名为k1的集合中添加abcd四个元素
(integer) 4
127.0.0.1:6379> SADD k2  b c d e
(integer) 4
127.0.0.1:6379> SCARD k1 //列出集合的大小
(integer) 4
127.0.0.1:6379> SMEMBERS k1 //列出集合中所有元素,可以看出“去重且乱序”的
1) "c"
2) "a"
3) "d"
4) "b"
127.0.0.1:6379> SISMEMBER k1 a //集合k1是否包含a
(integer) 1
127.0.0.1:6379> SISMEMBER k1 aa
(integer) 0
127.0.0.1:6379> sdiff k1 k2 //集合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> SRANDMEMBER k1 //从集合中随机取出(get)一个元素
"c"
127.0.0.1:6379> SRANDMEMBER k1
"b"
127.0.0.1:6379> SRANDMEMBER k1 3 //从集合中随机(这不废话吗,反正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 k1 3  //从集合中随机取出(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> SRANDMEMBER lotteryList -5 //如果为负数,会首先满足返回元素个数,可能会有重复
1) "tom"
2) "jerry"
3) "tony"
4) "jerry"
5) "jerry"

2. 奖品数<抽奖人数

扫描二维码关注公众号,回复: 12221938 查看本文章
127.0.0.1:6379> sadd lottoryList tom jerry jack tony lucy lily poly kevin
(integer) 8
127.0.0.1:6379> spop lottoryList 3 //三等奖
1) "jerry"
2) "jack"
3) "lily"
127.0.0.1:6379> spop lottoryList 2 //二等奖
1) "kevin"
2) "poly"
127.0.0.1:6379> spop lottoryList 1 //一等奖
1) "tony"

总结

我们稍微总结一下,类似抽奖这种简单随机场景,可以根据实际情况,考虑另一种思路,即使用Redis的 SRANDMEMBER 或者 spop 来实现。

好了,本次分享就是这样,我们下次讲 sorted_set,希望你能有收获。

猜你喜欢

转载自blog.csdn.net/H517604180/article/details/111084993