两种统计方式
滑动窗口(实时系统首选)
统计”当前往前推 N 小时”的下载数:
-- 1 小时下载量
SELECT COUNT(*) FROM downloads
WHERE download_time >= NOW() - INTERVAL 1 HOUR;
-- 3 小时下载量
SELECT COUNT(*) FROM downloads
WHERE download_time >= NOW() - INTERVAL 3 HOUR;
特点:平滑、不会整点突变,适合实时热榜、推荐系统、CDN 统计。
自然时间段(BI 报表常用)
按整点分桶,例如现在 15:37,统计范围是 15:00~15:59:
SELECT COUNT(*) FROM downloads
WHERE HOUR(download_time) = HOUR(NOW())
AND DATE(download_time) = CURDATE();
适合财务报表、数据仓库场景,不适合实时排行——整点会出现排名抽搐。
Redis 分钟桶(高并发推荐)
生产环境不会每次扫大表,而是用 Redis 分钟桶:
Key 格式:download:item:{id}:{yyyyMMddHHmm}
例如:download:item:123:202605281537
每次下载:
INCR download:item:123:202605281537
EXPIRE download:item:123:202605281537 86400
查询 1 小时:累加最近 60 个分钟 Key 查询 3 小时:累加最近 180 个分钟 Key
逻辑上是滑动窗口,底层是时间桶——抖音、B站、Steam 热榜的标准做法。
热度分值
单纯看 1 小时容易被刷量,实际排行榜通常组合多个时间窗口:
score = download_1h * 0.5
+ download_3h * 0.3
+ download_24h * 0.2
再叠加时间衰减因子防止老内容永远霸榜。
方案选型
| 场景 | 推荐方案 |
|---|---|
| 普通业务后台 | MySQL NOW() - INTERVAL |
| 高并发下载统计 | Redis 分钟桶 + 定时汇总 |
| 热门排序 | 1h + 3h + 24h 三个窗口组合 |
| 历史分析 / BI | ClickHouse 聚合 |
