数据表现状
- 用户表member,主要字段:用户id,当前总积分,当前冻结积分,用户昵称等;单表,几十万条记录
- 积分明细表,主要字段,记录id,用户id,积分数量,类型(增加或减少),积分来源,交易时间;目前分成8个表,总共是几千万条记录,而且记录增长快
需求
- 需要显示本周,月,季度,年的top(50)用户列表,显示用户的本周、本月、本季度、本年的积分数量,用户昵称,用户id
- 可以支持实时
问题
- 如果是直接从用户表和积分明细表联表查询sql,超时
解决思路
- 在用户表扩充字段(或者是新建一个表),暂时是用扩充字段的方式,增加字段:get_week_Points(周积分获取), resume_week_Points(周积分消耗),cur_week_Points(周留存积分),get_month_Points(月积分获取), resume_month_Points(月积分消耗),cur_month_Points(月留存积分),get_year_Points(年积分获取), resume_year_Points(年积分消耗),cur_year_Points(年积分水晶)
- 然后加几个时间字段,get_Points_Date(本周,月,季度,年的积分获取时更新时间),resume_Points_Date(本周,月,季度,年的积分消耗时更新时间),cur_Points_Date(本周,月,季度,年的积分留存时更新时间)
- 这样可以在一个表里面,查询用户的周,月,季度,年的top(N)记录了
- 用户表当前已经有用户的积分数,每一笔交易来的时候,相当于在当前记录额外的更新,改动较小(应该对数据库的写性能没有太多的影响)
数据填充 - 数据表扩展字段后,还需要把对应的用户记录填充进去
- 数据填充方式:周,月,季度,年的用户记录查询耗时,可以分散慢慢查询后填入(基本不影响数据库的正常业务)
- 定义一个方法,如generatePointsInfos(super_id),来生成记录,如果数据库为空,执行sql,生成单个用户的这些记录并插入表,数据库有该用户记录,跳过
- 可以在B端加一个入口,查询未填充的用户列表,循环遍历的去调用这个接口来刷新数据,比如可以在凌晨执行,也可以设置间隔等,不给数据库太多查询压力,可以手动的停止和启动该任务的执行。所有用户执行完成表示数据填充完成;
- 填充完成一次后,后续就不用再填充了
数据更新
- 更改积分逻辑,增加,过期,消耗的,都给在表里更新,逻辑是如果member表有该用户统计记录,在记录上增减后update;没有则跳过(表示数据还没刷到)
- 周,月,季度,年时间更新了,要去更新各个字段的值;a.可以用定时器去所有用户批量置零,b. 也可以用单个用户的对应的时间更新字段来判断,如判断已经是新的一周了,把旧数据清空更新