分时统计表+定时器,解决排行、报表等数据量大的业务场景
一、需求
项目业务在做一个攻略排行,要求每隔一段时间,更新排行榜
二、分析方案
-
redis缓存,先执行一次查询,然后缓存在redis中,下一次查询直接查询redis
缺点:占用内存,数据不实时,可能会出现缓存策略失效,接着把请求传到 mysql 中,这样请求也会变慢 -
分时统计表(大表转小表),这个表是专门统计数据的,先执行一次大表查询,然后将数据保存在分时统计表,下一次直接查询分时统计表
缺点:数据不实时
综上,攻略排行榜对于用户来说,时效性的需求没有那么强烈,抛开实时的缺点,采用大表转小表的方式十分契合我们的需求
三、技术
- 项目基于 SpringBoot,采用定时器,实现分时统计
- 统计(小)表设计
四、代码实现
Spring定时器
启动类需要贴注解 @EnableScheduling
@EnableScheduling
@SpringBootApplication
public class MgrApp {
public static void main(String[] args) {
SpringApplication.run(MgrApp.class, args);
}
}
编写定时任务
@Component
public class StrategyRankDataJob {
@Autowired
private IStrategyRankService strategyRankService;
/**
* 维护攻略排行表
* 每天早8点更新
*/
@Scheduled(cron = "0 0 8 * * *")
public void StrategyRankMaintain(){
strategyRankService.maintain(StrategyRank.TYPE_HOT);
}
}
服务实现层
@Override
public void maintain(Integer type) {
if (type != null) {
QueryWrapper<Strategy> wrapper = new QueryWrapper<>();
List<StrategyRank> strategyRankList = new ArrayList<>();
Date maintainTime = new Date();// 放外面,让下面整体更新时间一致
// 热门
/* select 列 from strategy order by (viewnum+replynum) desc limit 10*/
// 显示前 10 条
wrapper.select(列);
wrapper.orderByDesc("viewnum+replynum");
wrapper.last("limit 10");
List<Strategy> list = strategyService.list(wrapper);
for (Strategy strategy : list) {
StrategyRank strategyRank = new StrategyRank();
strategyRank.setXX(...);
strategyRankList.add(strategyRank);
}
super.saveBatch(strategyRankList);
}
}
以上,完成需求