历史数据回溯功能核心是“时间维度可选”,需前后端协同确保时间语义一致:前端用ISO格式传参并绑定真实查询参数,后端建索引支持高效时间过滤,缓存以时间范围为key,全程规避时区错位与全表扫描。

历史数据回溯功能的核心是“时间维度可选”而非“只存最新”
仪表盘默认只展示实时值,但业务上常需对比“今天 vs 昨天”“当前班次 vs 上一班次”“故障前5分钟 vs 故障后10分钟”。这要求前端能主动指定时间范围,后端能按需查历史,且缓存/存储策略不能丢数据。
前端时间选择器必须绑定到真实查询参数,不能只改UI
常见错误是加了个日期控件,但点击后图表没变化——因为没把 start_time 和 end_time 传给后端API。尤其注意时区:浏览器本地时间直接发给服务端,很可能因服务器在UTC而错位8小时。
- 用
input[type="datetime-local"]时,务必用toISOString()转成ISO格式(带Z),或手动补时区偏移 - 若后端用Python Flask,接收时用
datetime.fromisoformat(request.args.get("start_time")),别用strptime硬解析 - 默认时间范围建议设为最近1小时(
now - 3600),不是“今天0点”,避免空数据导致图表崩溃
后端查询必须支持时间过滤,且避免全表扫描
如果数据库表没对 timestamp 字段建索引,每次回溯都 SELECT * FROM sensor_data WHERE time > ? 会随着数据增长越来越慢。更糟的是,有些IoT采集系统把时间存在字符串字段里(如 "2026-10-27 21:30:00"),MySQL无法走索引。
- 确认时间字段类型是
DATETIME或TIMESTAMP,不是VARCHAR - 执行
EXPLAIN SELECT ... WHERE timestamp BETWEEN ? AND ?,确保type是range,不是ALL - 对高频写入的表(如每秒100条传感器数据),考虑按天分表,或用
WHERE date(timestamp) = '2026-10-27'配合函数索引(MySQL 8.0+)
前端缓存历史结果要带时间戳键,不能全局覆盖
用户切回“昨天”再切回“现在”,如果用同一个 lastFetchedData 变量存,第二次请求会直接返回旧数据,图表不刷新。必须把时间范围作为缓存key的一部分。
立即学习“前端免费学习笔记(深入)”;
- 缓存结构建议:
cache[`${start}_${end}_${metric}`] = { data, timestamp } - localStorage 存太多历史数据会撑爆配额(一般5MB),超过100条记录就该用 IndexedDB
- 不要在
useEffect里无条件触发回溯请求——得监听时间控件变更,而不是组件挂载就拉一次
关键点其实就一个:所有环节——从用户点日历、到HTTP请求参数、到SQL WHERE条件、再到前端渲染——必须共享同一套时间语义,中间任何一层转成本地时间又不校正,回溯就变成随机抽样。



















