抽奖问题

奖项 中奖人数 or 权重
1 500
5 100
10 20
50 5
100 1

区间

奖项 中奖人数 or 权重 区间
1 500 [0,500)
5 100 [500,600)
10 20 [600,620)
50 5 [620,625)
100 1 [625,626)

随机 rand = Rand([ 0 , sum(权重) ]) rand 在哪个区间就中什么。

问题

  • 如果先随机再减库存
    • 只抽sum(权重)次,大概率抽不完。如果有不中奖这个选项还好。
    • 极端奖项,大概率在最后抽到。
    • 可能会不断调整区间,剔除已抽到的项等
  • 库存减少要考虑并发

我的解法

  • 在mysql中准备好库存
  • 从库存中随机抽出 select * where xx=null order by rand() for update limit 1 锁住抽出的record
  • update 该记录 xx字段

保证并发,保证抽的完。