簽到功能,用 MySQL 還是 Redis ?
阿新 • • 發佈:2020-10-29
現在的網站和app開發中,簽到是一個很常見的功能,如微博簽到送積分,簽到排行榜。
如移動app ,簽到送流量等活動。
使用者簽到是提高使用者粘性的有效手段,用的好能事半功倍!
下面我們從技術方面看看常用的實現手段:
一. 方案1
直接存到資料庫MySQL
使用者表如下:
last_checkin_time 上次簽到時間
checkin_count 連續簽到次數
記錄每個使用者簽到資訊
簽到流程
1.使用者第一次簽到
last_checkin_time = time() checkin_count=1
2.使用者非第一次簽到,且當天已簽到
什麼也不做,返回已簽到。
3.使用者非第一次簽到,且當天還未簽到
a.昨天也有簽到
last_checkin_time = time() checkin_count= checkin_count+1
b.昨天沒有簽到
last_checkin_time = time() checkin_count=1
使用yii實現的程式碼如下:
//0點 $today_0 = strtotime(date('y-m-d')); //昨天0點 $yesterday_0 = $today_0-24*60*60; $last_checkin_time = $model->last_checkin_time;if(empty($last_checkin_time)){ //first checkin $model->last_checkin_time = time(); $model->checkin_count = 1; }else{ if($today_0 < $last_checkin_time){ //checkin ed 當天已簽到過 return json_encode(['code' => 0, 'msg' => '已簽到成功']); } //昨天簽到過 if($last_checkin_time < $today_0 && $last_checkin_time > $yesterday_0){ $model->last_checkin_time = time(); $model->checkin_count = $model->checkin_count + 1; }else{ //昨天沒簽到過,重新計數 $model->last_checkin_time = time(); $model->checkin_count = 1; }}$rs = $model->save();
二. 方案2
redis實現方案,使用bitmap來實現,bitmap是redis 2.2版本開始支援的功能,一般用於標識狀態,
另外 ,用bitmap進行當天有多少人簽到非常的方便,使用bitcount
redis->BITCOUNT($key);
簽到流程
設定兩個bitmap ,
一個以每天日期為key ,每個uid為偏移量
一個以使用者uid為key ,當天在一年中的索引為偏移量,
這樣記錄一個使用者一年的簽到情況僅需要365*1bit
以下是簽到程式碼
//每天一個key $key = 'checkin_' . date('ymd'); if($redis->getbit($key, $uid)){ //已簽到 return json_encode(['code' => 0, 'msg' => '已簽到成功']); }else{ //簽到 $redis->setbit($key, $uid, 1); $redis->setbit('checkin_'.$uid , date('z'), 1); }
以下是使用者連續簽到計算
public static function getUserCheckinCount($uid){ $key = 'checkin_'.$uid; $index = date('z'); $n = 0; for($i = $index; $i>=0;$i--){ $bit = Yii::$app->redis->getbit($key, $i); if($bit == 0) break; $n++; } return $n; }
以下是計算一天簽到使用者數
$key = 'checkin_' . date('ymd'); $redis = Yii::$app->redis;$count = $redis->BITCOUNT($key);
還有什麼需求呢?可以自己試著去實現
三. 優缺點比較
1.直接MySQL
思路簡單,容易實現;
缺點:佔用空間大,表更新比較多,影響效能,資料量大時需要用cache輔助;
2.Redis bitmap
優點是:
佔用空間很小,純記憶體操作,速度快;
缺點是 :
記錄的資訊有限,只有一個標識位;
偏移量不能大於2^32,512M;大概可以標識5億個bit位,絕大多數的應用都是夠用的啦;
偏移量很大的時候可能造成 Redis 伺服器被阻塞;所以要考慮切分。
好啦,介紹完了,各有利弊,你喜歡哪種方式呢?
歡迎討論!
作者:一起web程式設計
來源:http://suo.im/5EWN3k