每日访问量统计的一种实现

本文介绍了一种利用Redis进行数据集访问量实时计数的方法,通过在数据库中存储每日访问量并定期从Redis同步到数据库,以提高查询效率。同时,展示了如何设计数据库表结构和使用定时任务来实现这一过程,但并未处理失败补偿的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计需求是记录数据集的每日访问量,可以进行趋势查看。

最简单的就是直接每次操作记录日志,然后在查询时直接根据日志使用sql实时统计。这种方案很简单,不需要另外考虑存储结构,只要查询语句写好即可。但是对于数据量稍微大一些的场景,这种方式的效率将会非常差。
因此这里考虑将每日访问量在数据库中存储下来,然后查询的时候能直接查即可。

思路就是设计表将数据集、日期共同作为复合主键,存储访问量数据。
由于在这个表中设计每人访问加1,直接更新这个表的话代价会比较大

sql表结构

CREATE TABLE `g_dataset_visit_count` (
  `dataset_id` bigint(11) NOT NULL COMMENT '数据集id',
  `v_date` datetime NOT NULL COMMENT '日期',
  `v_count` int(255) DEFAULT NULL COMMENT '访问量',
  `type` tinyint(4) DEFAULT NULL COMMENT '类型:1、数据页访问;2、接口查询',
  PRIMARY KEY (`dataset_id`,`v_date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

使用redis进行计数

	@Resource
	StringRedisTemplate stringRedisTemplate;
	@Autowired
	DatasetProjectMapper datasetProjectMapper;
	
	/**
	 * 更新访问量:即时更新数据集表的访问量,更新redis中存储的当前访问量;然后在定时器中每晚更新日期访问表中的量
	 */
	public void visitDataset(Long datasetId, int Source) {
		// 更新数据集表的数量
		String redisKey = "dset_v_" + datasetId;
		stringRedisTemplate.opsForValue().increment(redisKey);
		// 给哪个数据集的哪个字段加1
		datasetProjectMapper.pageVisitIncre(datasetId, Source);
	}

定时任务持久化

@Component
@EnableScheduling
public class DatasetVisitInitJob {

	@Resource
	StringRedisTemplate stringRedisTemplate;
	@Autowired
	DatasetProjectMapper datasetProjectMapper;
	@Autowired
	DatasetVisitCountMapper datasetVisitCountMapper;
	
	@Scheduled(cron = "0 30 23 * * ?")
	public void createHyperLog() {
	    // 先更新日期;然后重新写入
		// 查出所有数据集的id,遍历查找当前访问量,按当前日期插入数据库
		List<Long> ids = datasetProjectMapper.getIds();
		LocalDate now = LocalDate.now();
		for (Long item : ids) {
			// 查redis,并按当前日期插入
			String redisKey = "dset_v_" + item;
			Object rv = stringRedisTemplate.opsForValue().get(redisKey);
//			if (rv == null) {
//				redisTemplate.opsForValue().set(redisKey, 0);
//			}
			DatasetVisitCount dvc = new DatasetVisitCount();
			try {				
				dvc.setVCount(Integer.parseInt(rv.toString()));
			} catch (Exception e) {
				dvc.setVCount(0);
			}
			dvc.setDatasetId(item);
			dvc.setVDate(now);
			dvc.setType(1);
			datasetVisitCountMapper.insert(dvc);
			Object c = stringRedisTemplate.opsForValue().getAndSet(redisKey, "0");
		}
	}
}

以上由于时间问题暂未处理失败补偿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值