商城接到一个需求,有以下几个要求:
增加签到的功能,1号签到增加1个积分,2号签到增加2个积分,以此类推。
连续签到第6日,15日,25日分别奖励积分50,70,100个积分。
每天能补签一次。
用户能查看历史几个月的签到记录。
签到好做,用ajax提交就好。
可是问题是:根据以上需求,怎么存储数据较好。
把签到的日期放在sign_record
中,以逗号隔开。
user_id | date_month | sign_record |
---|---|---|
1 | 2015-08 | 1,2,3,4,5,7,8,9,10... |
2 | 2015-08 | 7,8,9,10... |
3 | 2015-08 | 1,7,8,9,10... |
... | ... | ... |
把签到的日期放在sign_record
中,
user_id | date | sign_record |
---|---|---|
1 | 2015-08 | 1 |
1 | 2015-08 | 2 |
1 | 2015-08 | 3 |
1 | 2015-08 | 4 |
2 | 2015-08 | 2 |
... | ... | ... |
上面两种的话我偏向于第一种,但是可能不符合三范式。
有没有其他的方式来存储呢,请大大们支招。
刚好我以前做过类似的一个数据库设计,给你一个思路
这个明显是需要两张表来进行共同存储(就是把你的第一张表跟第二张结合)
表A存储的为
| userid | lastsign| consigncount |
| 1 | 2015-08-28 | 2 |
这个consigncount存储的是用户连续签到的天数
表B跟你表二的结构一样
这其实是两个需求,一个需求叫连续签到获得积分,另一个需求叫查看签到记录
表A你可以理解为统计表
每次用户签到的时候判断逻辑为
1用户签到 2查询表B判断是否为连续签到(查询昨天的签到记录)
流程结束
我也认同楼主采用第一种.
因为查询的条件主要还是落在
user_id
和date_month
上,然后拿到用户的签到记录
sign_records
,再用explode以逗号分割转成数组进行积分计算.
建议
date_month
使用时间戳存储:strtotime('2015-08')
得1438358400字段类型刚好可以选择int(10),同时建立索引,加速查询.
因为签到记录
sign_records
都是整数,可以用intval()
保证插入的值是整数.以逗号分隔存入字段并无不妥,省去了序列化或者JSON的编解码操作,同时还方便使用MySQL的
FIND_IN_SET
函数以sign_records
字段为条件进行查询,这都是逗号分隔的好处:比如查询在8月1日签到的用户:
个人见解是:
1.数据表的字段“datamonth”改为“dataday”按天来记录签到。
2.具体的分值根据签到天数计算:
我不是大神,只是说说我的看法。
使用JSON存储
MySQL的话建议用JSON, MySQL 5.7原生JSON格式支持.
用某种符号进行分割建议尽量避免, 日期比较简单. 如果复杂的数据就很容易出错. 能有稳健的数据结构就用数据结构.
使用触发器
可以使用触发器来处理积分什么的.
第一种,但是增加一个字段,就是连续签到次数,补签应该是出发比较少的行为吧