前言
但凡商戶搞點營銷活動,為了能觸達更多的顧客,來點兒抽獎的把戲,應該是極好的,什么“刮刮樂”、“砸金蛋”、“大轉盤”等等,換湯不換葯,屢試不爽。從微客多營銷平台各種活動的使用情況也能看出,抽獎活動一直是商戶用得最多的線上活動,正所謂無利不起早,給點“花蜜”犒勞下“蜜蜂”也是應該的。
需求分析
那么問題來了,發獎機制怎么玩?作為一個服務商戶的營銷平台,怎樣將商戶配置的獎品發出去才能起到比較好的效果呢?
先來看目標,什么是比較好的效果,也就是用戶(商戶)的需求是什么:
- 抽獎活動期間獎品數量是固定的
- 稀有的獎品盡量靠后被抽中
- 物盡其用,獎品不希望有剩余
- 每個獎品可以設置被抽中的概率
場景模擬
為了討論方便,我們先把場景假設一下:
抽獎活動時間:
00:00:00-23:59:59
獎品設置:
獎品級別 | 獎品名稱 | 獎品數量 |
一等獎 | A | 2 |
二等獎 | B | 3 |
三等獎 | C | 4 |
具體分析
第一種能想到的做法就是給每種獎品設置中獎概率,每次按設置好的中獎概率派獎,但是問題又來了:
獎品數量固定,但是參與抽獎的人數不可預知,根本無法控制獎品的消耗速度,如果概率設置高了,抽獎者一擁而上獎品很快就沒了,設置低了,獎品可能到最后都發不完。另外,概率這個偏技術的術語用戶理解起來肯定五花八門,使用時溝通成本非常高。
而實際上“每個獎品可以設置被抽中的概率”是個十分模糊的說法,說它模糊,主要是因為你並不知道這個設置的概率用在什么地方,這些概率設置需要滿足什么條件,總樣本數量(總抽獎次數)是多少。
所以最好的做法應該是用戶不必關心所謂的“獎品被抽中的概率”,只關注前三個預期效果即可。
經過分析,我們發現,要達到用戶上面的那三個效果,只要獎品在活動期間陸續被抽走即可,那能不能給每件獎品設置一個允許被抽走的時間呢?對!如果控制好每件獎品的發放時間點,再安排好各類獎品的發放順序,大獎不會一開始就抽走,直到活動最后階段都能保證有獎。
具體設計
順着這個想法,我們來看具體的設計:
將獎品均勻地埋在整個活動時間(3600*24=86400秒)里,如上面假設場景,一共有9個獎品,則把活動時間均勻的分成9份
以獎品剩余數量作為權重,陸續隨機選擇每個時間段里的獎品類型(顏色對應的獎品見上表)
在每個時間段里隨機選擇獎品的“釋放”時間點,一是為了均勻,二是避免直接暴露精確的時間點
1
|
releaseTime(n)=startTime+(n-1)× ∆t+random(∆t)
|
實現方案
說完思路,我們再看實現:在獎品釋放時間點之后的抽獎用戶就有機會(這個概率可配置,如100%或者80%)拿到該時間段的獎品,如果獎品未被抽走,將繼續等待抽獎者的到來。
思路一
直觀的做法是建立三張表
t_award_batch(獎品描述表,用於記錄各種獎品的配置信息),
ID | 名稱(name) | 獎品總量(amount) |
1 | A | 2 |
2 | B | 3 |
3 | C | 4 |
t_award_pool(獎池表,用於生成每一次獎品釋放的時間點),
ID | 獎品ID(award_id) | 釋放時間(release_time) | 剩余數(balance) |
1 | 3 | 1:03:27 | 0 |
2 | 2 | 3:15:13 | 1 |
3 | 3 | 5:29:57 | 1 |
4 | 2 | 9:35:34 | 1 |
5 | 1 | 12:57:20 | 1 |
6 | 2 | 13:47:03 | 1 |
7 | 3 | 17:31:50 | 1 |
8 | 1 | 18:13:26 | 1 |
9 | 3 | 22:28:40 | 1 |
t_record(抽獎記錄表,用於記錄每次抽獎者的抽獎記錄)
ID | 獎品ID(award_id) | 中獎時間(hit_time) | 用戶ID(owner_id) |
1 | 3 | 1:03:45 | peteryan |
活動開始前,根據t_award_batch中的獎品配置信息,初始化t_award_pool中的數據,把每種獎品的釋放時間初始化好,用戶來抽獎時,根據當前時間在t_award_pool表中的查詢到一條已經釋放而且未被抽掉的獎品
1
|
select id from t_award_pool where release_time <= now() and balance > 0 limit 1 ;
|
查詢到后對其進行更新,如果被他人搶走,則未中獎
1
|
update t_award_pool set balance = balance – 1 where id = #{id} balance > 0 ;
|
同時留下抽獎情況到t_record中。
思路二
在思路一中,為了方便抽獎時判斷當前是否有可中獎品,進行了初始化每件獎品的釋放時間,當獎品數量比較小的時候,情況還好,對於獎品數非常多的時候,抽獎的查詢耗時會增加,初始化獎池也是耗時的動作,是否可以不依賴這個表之間通過實時計算判斷當前是否有獎品釋放。
在t_award_batch表中添加兩個字段,獎品總剩余量balance和上一次中獎時間last_update_time。
ID | 名稱(name) | 獎品總量(amount) | 獎品余量(balance) | 更新時間(last_update_time) |
1 | A | 2 | 2 | 1:03:45 |
2 | B | 3 | 3 | 0:00:00 |
3 | C | 4 | 3 | 0:00:00 |
這樣具體實現上僅需要依賴獎品配置信息即可,示例代碼如下(點擊圖片全屏查看):
其中awardBatch表示一類獎品,如上表中提到的一等獎。上面代碼中,隨機選出下一個待釋放的獎品邏輯如下:
通過這套發獎機制,很好地滿足了營銷商戶的目標,同時減少了對復雜概率計算的糾結,再也不用擔心獎品被提前搶光了。