MySQL利用int类型高性能实现签到活动
#头条创作挑战赛#一:需求背景
产品签到活动需求,对于日活量不高的程序,可以直接使用MySQL去处理,当然数据量不大的话,签到一次,数据库签到表保存一条记录,也是可以的。但是如果类似京东等商城,那种签到活动,日活好几亿,并且并发也很高,这样不断疯狂进行数据库读写操作,MySQL压力是很大的。
那怎么解决呢?
二:解决方案
可以利用MySQL,定义一个int类型的字段,4byte=32位,存储一个月的数据,每次签到,改变这个字段,程序代码进行二进制逻辑预算,数据库该值存储十进制,优化成一行数据存一个人一个月的签到记录。一般商城促销活动签到,一个月一个周期已经可以了。
三:代码实现
代码实现前,先来复习一下逻辑运算和签到逻辑:
1.数据库保存签到记录,int类型,4 byte = 32位可以存储一周或者一个月数据 周1:0000 0001 == 1 周2:0000 0010 == 2 周3:0000 0100 == 4 周4:0000 1000 == 8 周5:0001 0000 == 16 周6:0010 0000 == 32 周7:0100 0000 == 64 2.异或 ^ 、与 & 、或 | 逻辑运算: 异或 ^:两者不一样,eg 1^0,0^1 得出结果就是 1,其他1^1,0^0都是0 与 &: 只有两者都是是 1 ,eg 1&1 得出结果就是 1,其他都是0 或 |: 两者有一个是 1 ,eg 1^0,0^1,1^1 得出结果就是 1,其他都是0
所以根据上面分析,可以得出以下模拟每天签到的案例(ps:<< 表示左移):
第一天签到: 1 << 0 == 0000 0001 这时数据库存的是 1 第二天签到: 1 << 1 == 0000 0010,此时数据保存前一天签到 0000 0001,所以需要两个数据合成一个,可以用 异或 ^ 或者 或 | 0000 0010 | 0000 0001 = 0000 0011 或者 0000 0001 ^ 0000 0010 = 0000 0011 这时数据库存的是 0000 0011 = 3 第三天签到: 1 << 2 == 0000 0100, 数据库存的是 0000 0011 0000 0100 | 0000 0011 = 0000 0111 或者 0000 0100 ^ 0000 0011 = 0000 0111 这时数据库存的是 0000 0111 = 7 第四天没有签到 第五天签到: 1 << 4 == 0001 0000, 数据库存的是 0000 0111 0001 0000 | 0000 0111 = 0001 0111 或者 0001 0000 ^ 0000 0111 = 0001 0111 ........
业务层代码实现,为了方便,代码模拟一周为一个周期进行签到:
/** * 签到并领取奖励 * @param uid * @param day 第几天 * @return 签到成功返回奖励 */ public Integer rewardReceiveByDB(String uid, int day) { // 查询当前一周,该用户是否签到记录 LocalDate now = LocalDate.now(); LocalDateTime startTime = LocalDateTime.of(now.with(DayOfWeek.MONDAY), LocalTime.MIN); LocalDateTime endTime = LocalDateTime.of(now.with(DayOfWeek.SUNDAY), LocalTime.MAX); // 查询是否有本周签到记录,一周只有一条记录 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("uid", uid) .ge("ctime", startTime) .le("ctime", endTime); SignLog signLog = signLogService.getOne(wrapper); if (signLog == null){ signLog = new SignLog(); signLog.setUid(uid); signLog.setFlag(0); } /* 1 << 2 == 0000 0100, 数据库存的是 0000 0011 0000 0100 | 0000 0011 = 0000 0111 或者 0000 0100 ^ 0000 0011 = 0000 0111 */ int signFlag = signLog.getFlag(); // 二进制下标 0开始 signFlag = signFlag | (1 << (day - 1)); signLog.setFlag(signFlag); signLogService.saveOrUpdate(signLog); // Integer.bitCount直接统计,签到了几天,发奖励 long signInDays = Integer.bitCount(signFlag); // todo 根据业务需求,发送奖励 return rewardMap.get(signInDays); } /** * 查看用户在某一天是否签到了 * @param uid * @param day 第几天 * @return */ @Override public boolean getSignStatus(String uid, int day) { /** * 判断某一天 day 该用户是否签到 * 可用 某一天 day 签到的 二进制值 跟 当前数据的值 进行 与& 操作,也就是二进制位只有 day 位置是 1,其他都是0, * 如果跟它进行 与& 操作 如果数据库值当天签到 就会 等于 1 */ LocalDate now = LocalDate.now(); LocalDateTime startTime = LocalDateTime.of(now.with(DayOfWeek.MONDAY), LocalTime.MIN); LocalDateTime endTime = LocalDateTime.of(now.with(DayOfWeek.SUNDAY), LocalTime.MAX); // 查询是否有本周签到记录,一周只有一条记录 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("uid", uid) .ge("ctime", startTime) .le("ctime", endTime); SignLog signLog = signLogService.getOne(wrapper); if (signLog == null){ return false; } Integer flag = signLog.getFlag(); // 当天签到的二进制值 int signFlag = 1 << (day - 1); return (flag & signFlag) == 1; }
四:总结
个人觉得,具体实现根据公司的业务体量来决定。但是条件允许的话,确实可以用位存储来实现。其实redis的一个数据类型bitmap也是根据位来实现。方便一点的,可以知己义工redis的bitmap来实现,这样完全就不用经过数据库,但是如果需要归因的话,数据库保存发送签到奖励的记录即可。
本人bitmap实现签到:https://blog.csdn.net/qi_ming88/article/details/102716469
海月幻境太无敌!传送闪现都没用,他们却能击败外面的人上线体验服的新英雄海月,妥妥的长腿大美女,定位法师特长能强行单挑我今天可不是来介绍海月的玩法的,毕竟各大博主对她的玩法出装等都做了比较详细的介绍,而我村某人接下来要给大家聊聊海月的
地铁跑酷直充皮肤怎么获得?地铁跑酷直充皮肤是怎么得到的?最近很多人都在讨论这个辅助工具,玩家可以在地铁跑酷直充上传游戏数据,领皮肤的方法小编这就分享在下面,各位玩家可以通过下面的攻略快速的了解地铁跑酷直充获
出伏后,照顾孩子记住2不吃2不做,孩子不易生病长得快导语出伏后,照顾孩子记住2不吃2不做,孩子不易生病长得快暑天终于熬过去了,出伏后气温降了不少,让人感到舒适很多,但出伏后,昼夜温差大,天气还很干燥,而孩子的抵抗力比较差,极容易在这
17个部门出台积极生育支持政策,利好多多,对提高生育率有哪些帮助?今天咱们来说一说关于鼓励生育的政策。众所周知,咱们国家已经步入到了人口老龄化的社会,而且近些年来生育率不断走低。为了解决这个问题,咱们国家出台了三胎政策,开始大力地鼓励生育。就在最
脐带血存储成智商税,谁在忽悠牟利作者熊志自费储存脐带血已经成为一门炙手可热的生意。多名孕妇向新京报记者表示,自己在医院做产检时,会遇到身穿白大褂的推销人员,通过各种渠道推销脐带血储存服务。脐带血储存服务附赠医疗保
为什么孩子就是不听话不爱学习?他的自主选择权被你干扰了大家好,我是倡导人人如龙的镭师兄,今天我们聊一下自主选择权妨碍这个认知偏差。一这个画面熟悉吗?父母最头疼的情况之一是下面的场景孩子看了半天的动画片,在动画片播放快结束时,你实在忍不
泰国华富里府的猴子8月24日,猴子在泰国华富里府玩耍。泰国中部的华富里府以猴子众多闻名,每年都有大量游客来此观赏猴群。新华社发(拉亨摄)8月24日,猴子在泰国华富里府玩耍。泰国中部的华富里府以猴子众
汨罗旅游宣传口号和旅游形象标识征集作品初评启动来源汩罗市人民政府网资讯汨罗融媒体讯(记者刘胜丹通讯员郑强)8月22日,汨罗旅游宣传口号和旅游形象标识征集作品初评会议在文旅广电局召开。评选工作小组向评审专家组就评审标准时间要求进
暗光子开启暗物质世界的一枚钥匙?暗物质是当今物理学前沿的基本问题之一。物理学家提出了多种暗物质模型,本文将介绍其中一种暗光子。它是一种矢量规范玻色子,有着与光子类似的特性,并且其质量范围较广。暗光子首先是作为连接
PoP热电子破坏冲击点火过程核聚变研究的主要目标是理解如何最大限度地获得的核聚变能量也就是说,以最小的输入能量产生最大的输出能量。一项很有前景的技术是冲击点火,这是一种用于直接驱动惯性约束聚变的技术,有可能以
轲比能,一个鲜卑族首领,一顿操作把部落整得蒸蒸日上了轲比能,一个鲜卑族首领,一顿操作把部落整得蒸蒸日上了三国杀本期小叮当要给大家带来的是是一个具有超高配合性和兼容性的趣味武将,轲比能。这个人是鲜卑首领,学习汉族先进文化和技术,把他的