今天看下簽到功能怎么選擇窍蓝?
現(xiàn)在的網(wǎng)站和app開發(fā)中腋颠,簽到是一個(gè)很常見的功能,如微博簽到送積分吓笙,簽到排行榜
微博簽到
如移動(dòng)app 淑玫,簽到送流量等活動(dòng),
移動(dòng)app簽到
用戶簽到是提高用戶粘性的有效手段面睛,用的好能事半功倍絮蒿!
更多java干貨技能全在微信:YDT939里面,更多面試專題叁鉴、筆記歌径、資料免費(fèi)領(lǐng)取
下面我們從技術(shù)方面看看常用的實(shí)現(xiàn)手段:
一. 方案1
直接存到數(shù)據(jù)庫MySQL
用戶表如下:
last_checkin_time 上次簽到時(shí)間
checkin_count 連續(xù)簽到次數(shù)
記錄每個(gè)用戶簽到信息
簽到流程
1.用戶第一次簽到
last_checkin_time?=?time()
checkin_count=1
2.用戶非第一次簽到,且當(dāng)天已簽到
什么也不做亲茅,返回已簽到回铛。
3.用戶非第一次簽到狗准,且當(dāng)天還未簽到
a.昨天也有簽到
last_checkin_time?=?time()
checkin_count=?checkin_count+1
b.昨天沒有簽到
last_checkin_time?=?time()
checkin_count=1
使用yii實(shí)現(xiàn)的代碼如下:
//0點(diǎn)
$today_0=?strtotime(date('y-m-d'));
//昨天0點(diǎn)
$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?當(dāng)天已簽到過
returnjson_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{
//昨天沒簽到過,重新計(jì)數(shù)
$model->last_checkin_time?=?time();
$model->checkin_count?=?1;
}}$rs=$model->save();
二. 方案2
redis實(shí)現(xiàn)方案茵肃,使用bitmap來實(shí)現(xiàn)腔长,bitmap是redis 2.2版本開始支持的功能,一般用于標(biāo)識(shí)狀態(tài)验残,
另外 捞附,用bitmap進(jìn)行當(dāng)天有多少人簽到非常的方便,使用bitcount
redis->BITCOUNT($key);
簽到流程
設(shè)置兩個(gè)bitmap ,
一個(gè)以每天日期為key 您没,每個(gè)uid為偏移量
一個(gè)以用戶uid為key 鸟召,當(dāng)天在一年中的索引為偏移量,
這樣記錄一個(gè)用戶一年的簽到情況僅需要365*1bit
以下是簽到代碼
//每天一個(gè)key
$key='checkin_'.?date('ymd');
if($redis->getbit($key,$uid)){
//已簽到returnjson_encode(['code'=>?0,'msg'=>'已簽到成功']);
}else{
//簽到$redis->setbit($key,$uid,?1);
$redis->setbit('checkin_'.$uid,?date('z'),?1);
}
以下是用戶連續(xù)簽到計(jì)算
public?staticfunctiongetUserCheckinCount($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;
}
以下是計(jì)算一天簽到用戶數(shù)
$key='checkin_'.?date('ymd');
$redis=?Yii::$app->redis;$count=$redis->BITCOUNT($key);
還有什么需求呢氨鹏?可以自己試著去實(shí)現(xiàn)
三. 優(yōu)缺點(diǎn)比較
1.直接MySQL
思路簡(jiǎn)單欧募,容易實(shí)現(xiàn);
缺點(diǎn):占用空間大仆抵,表更新比較多跟继,影響性能,數(shù)據(jù)量大時(shí)需要用cache輔助镣丑;
2.Redis bitmap
優(yōu)點(diǎn)是:
占用空間很小舔糖,純內(nèi)存操作,速度快莺匠;
缺點(diǎn)是 :
記錄的信息有限金吗,只有一個(gè)標(biāo)識(shí)位;
偏移量不能大于2^32趣竣,512M摇庙;大概可以標(biāo)識(shí)5億個(gè)bit位,絕大多數(shù)的應(yīng)用都是夠用的啦期贫;
偏移量很大的時(shí)候可能造成 Redis 服務(wù)器被阻塞跟匆;所以要考慮切分。
好啦通砍,兩種方式介紹完了玛臂,各有利弊,你喜歡哪種方式呢封孙?
歡迎討論迹冤!
更多java干貨技能全在微信:YDT939里面,更多面試專題虎忌、筆記泡徙、資料免費(fèi)領(lǐng)取