签到功能,用 MySQL 还是 Redis ?
现在的网站和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
签到功能,用 MySQL 还是 Redis ?的更多相关文章
- 用Redis实现签到功能
一.场景 在很多时候我们会遇到用户签到的场景,每天用户进入应用时,需要获取用户当天的签到状态,如果没签到,用户可以进行签到,并且得到相关的奖励.我们可能需要每天的签到情况,必要的时候可能还需要统计一下 ...
- Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- Redis实战篇(二)基于Bitmap实现用户签到功能
很多应用上都有用户签到的功能,尤其是配合积分系统一起使用.现在有以下需求: 签到1天得1积分,连续签到2天得2积分,3天得3积分,3天以上均得3积分等. 如果连续签到中断,则重置计数,每月重置计数. ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步
[TOC] 1, 环境 CentOS, MySQL, Redis, Nodejs 2, Redis简介 Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list ...
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...
- Docker 小记 — MySQL 与 Redis 配置
前言 本篇随笔是继 "Docker Engine" 与 "Compose & Swarm" 之后的一个实例补充,初衷是记录测试环境中的一次 MySQL ...
- [转]mysql和redis的区别
转自https://www.cnblogs.com/zxh1297/p/9394108.html 1.mysql和redis的数据库类型 mysql是关系型数据库,主要用于存放持久化数据,将数据存储在 ...
- mysql和redis的区别
一..redis和mysql的区别总结 (1)类型上 从类型上来说,mysql是关系型数据库,redis是缓存数据库 (2)作用上 mysql用于持久化的存储数据到硬盘, ...
随机推荐
- Android如何使用注解进行代码检查
原文首发于微信公众号:躬行之(jzman-blog),欢迎关注交流! Android Studio 内置了代码检查工具 Lint,可在菜单栏选择 Analyze > Inspect Code 执 ...
- 【记】《.net之美》之读书笔记(一) C#语言基础
前言 工作之中,我们习惯了碰到任务就直接去实现其业务逻辑,但是C#真正的一些基础知识,在我们久而久之不去了解巩固的情况下,就会忽视掉.我深知自己正一步步走向只知用法却不知原理的深渊,所以工作之余,一直 ...
- linux_基础调优
1. 配置授时服务,使用阿里云的授时服务 echo -e "# update time\n*/5 * * * * /usr/sbin/ntpdate time1.aliyun.com &am ...
- C++ 双冒号开头的语法是什么
z转载:https://blog.csdn.net/LHHopencv/article/details/78353380 命名空间限定.std::string 表示std命名空间下的 string类. ...
- QTree1 【题解】
题目背景 数据规模和spoj上有所不同 题目描述 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时 ...
- Linux下clock子系统
常用API: 1.struct clk *clk_get(struct device *dev, const char *id):从一个时钟list链表中以dev或者字符id名称查找一个时钟clk结构 ...
- MeteoInfoLab脚本示例:计算垂直螺旋度
尝试编写MeteoInfoLab脚本计算垂直螺旋度,结果未经验证. 脚本程序: print 'Open data files...' f_uwnd = addfile('D:/Temp/nc/uwnd ...
- MeteoInfoLab脚本示例:TOMS HDF数据
TOMS (Total Ozone Mapping Spectrometer)数据是全球臭氧观测.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = ...
- selenium登录163邮箱,得到cookie,requests后续请求
1.场景 很多时候登录操作是比较复杂的,因为存在各种反爆破操作,以及为了安全性提交数据都会存在加密.如果要完全模拟代码去实现登录操作是比较复杂,并且该网站后续更新了登录安全相关功能,那么登录的模拟操作 ...
- python知识点整理一
1.数组元素之和 解法一 from functools import reduce list=[1,3,5,7,9,34] print(reduce(lambda x,y:x+y,list)) 解法二 ...