前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >签到功能,用 MySQL 还是 Redis ?

签到功能,用 MySQL 还是 Redis ?

作者头像
java进阶架构师
发布2020-10-23 10:16:08
1.8K0
发布2020-10-23 10:16:08
举报
文章被收录于专栏:Java进阶架构师

2020年Java原创面试题库连载中

【000期】Java最全面试题库思维导图

【020期】JavaSE系列面试题汇总(共18篇)

【028期】JavaWeb系列面试题汇总(共10篇)

【042期】JavaEE系列面试题汇总(共13篇)

【049期】数据库系列面试题汇总(共6篇)

【053期】中间件系列面试题汇总(共3篇)

【065期】数据结构与算法面试题汇总(共11篇)

【076期】分布式面试题汇总(共10篇)

【077期】综合面试题系列(一)

【078期】综合面试题系列(二)

【079期】综合面试题系列(三)

【080期】综合面试题系列(四)

【081期】综合面试题系列(五)

【082期】综合面试题系列(六)

【083期】综合面试题系列(七)

【084期】综合面试题系列(八)

【085期】综合面试题系列(九)

【086期】综合面试题系列(十)

【087期】综合面试题系列(十一)

【088期】综合面试题系列(十二)

【089期】综合面试题系列(十三)

更多内容,点击上面蓝字查看

作者:一起web编程

来源:http://suo.im/5EWN3k

今天看下签到功能怎么选择?

现在的网站和app开发中,签到是一个很常见的功能,如微博签到送积分,签到排行榜

微博签到

如移动app ,签到送流量等活动,

移动app签到

用户签到是提高用户粘性的有效手段,用的好能事半功倍!

下面我们从技术方面看看常用的实现手段:

一. 方案1

直接存到数据库MySQL

用户表如下:

last_checkin_time 上次签到时间

checkin_count 连续签到次数

记录每个用户签到信息

签到流程

1.用户第一次签到

代码语言:javascript
复制
last_checkin_time = time()
checkin_count=1

2.用户非第一次签到,且当天已签到

什么也不做,返回已签到。

3.用户非第一次签到,且当天还未签到

a.昨天也有签到

代码语言:javascript
复制
last_checkin_time = time()
checkin_count= checkin_count+1

b.昨天没有签到

代码语言:javascript
复制
last_checkin_time = time()
checkin_count=1

使用yii实现的代码如下:

代码语言:javascript
复制
//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

count =

redis->BITCOUNT($key);

签到流程

设置两个bitmap ,

  • 一个以每天日期为key ,每个uid为偏移量
  • 一个以用户uid为key ,当天在一年中的索引为偏移量,

这样记录一个用户一年的签到情况仅需要365*1bit

以下是签到代码

代码语言:javascript
复制
//每天一个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);
  }

以下是用户连续签到计算

代码语言:javascript
复制
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;
 }

以下是计算一天签到用户数

代码语言:javascript
复制
$key = 'checkin_' . date('ymd');
$redis = Yii::$app->redis;$count = $redis->BITCOUNT($key);

还有什么需求呢?可以自己试着去实现

三. 优缺点比较

1.直接MySQL

思路简单,容易实现;

缺点:占用空间大,表更新比较多,影响性能,数据量大时需要用cache辅助;

2.Redis bitmap

优点是:

占用空间很小,纯内存操作,速度快;

缺点是 :

记录的信息有限,只有一个标识位;

偏移量不能大于2^32,512M;大概可以标识5亿个bit位,绝大多数的应用都是够用的啦;

偏移量很大的时候可能造成 Redis 服务器被阻塞;所以要考虑切分。

好啦,两种方式介绍完了,各有利弊,你喜欢哪种方式呢?

欢迎讨论!

代码语言:javascript
复制
之前,给大家发过三份Java面试宝典,这次新增了一份,目前总共是四份面试宝典,相信在跳槽前一个月按照面试宝典准备准备,基本没大问题。《java面试宝典5.0》(初中级)《350道Java面试题:整理自100+公司》(中高级)《资深java面试宝典-视频版》(资深)《Java[BAT]面试必备》(资深)分别适用于初中级,中高级,资深级工程师的面试复习。内容包含java基础、javaweb、mysql性能优化、JVM、锁、百万并发、消息队列,高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper、数据结构、限流熔断降级等等。获取方式:点“在看”,V信关注上述Java最全面试题库号并回复 【面试】即可领取,更多精彩陆续奉上。
看到这里,证明有所收获必须点个在看支持呀,喵
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java进阶架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 方案1
    • 签到流程
    • 二. 方案2
      • 签到流程
      • 三. 优缺点比较
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档