16 时序数据与聚合¶
难度:中级|前置:数据库、MQTT|目标:从数据量和查询模式设计遥测存储
先算数据量¶
10 万设备,每 30 秒上报一次:
如果每条原始记录加索引、元数据后占 300 字节:
这只是粗估,但足以说明不能“先全存,之后再说”。
区分三类数据¶
| 数据 | 示例 | 特点 |
|---|---|---|
| 最新状态 | 当前温度、电量 | 高频读取,只需最新值 |
| 原始遥测 | 每次上报 | 写多、按时间查询 |
| 聚合数据 | 5 分钟均值、日最大值 | 用于趋势和报表 |
不要为了查当前值,每次扫描最新一条原始遥测。
表设计¶
时序表常见维度:
宽表还是窄表取决于指标稳定性和查询模式。没有一种模型适合所有设备类型。
时间分区¶
TimescaleDB Hypertable 按时间自动分为 chunk。查询带时间范围时只扫描相关 chunk。
仍然需要:
- 合理 chunk 大小;
- 常见查询索引;
- 避免无时间范围的全表扫描;
- 控制每条记录索引数量。
聚合和降采样¶
页面显示 30 天趋势不需要返回每 30 秒一个点。可以预计算:
- 1 分钟;
- 5 分钟;
- 1 小时;
- 1 天。
聚合保存 count、min、max、avg,而不只保存 avg,否则无法正确继续合并。
TimescaleDB Continuous Aggregate 可以增量维护聚合,降低反复扫描原始数据的成本。
保留策略¶
例如:
删除原始数据前,要确认所需聚合已经刷新完成。保留策略是产品和合规决策,不只是数据库配置。
乱序和设备时间¶
设备时钟可能不准。建议同时考虑:
- device_time;
- server_received_time;
- 时钟质量;
- 允许的迟到窗口;
- 聚合如何修正迟到数据。
自测¶
- 为什么最新状态不应每次从原始遥测中查?
- 10 万设备 30 秒上报的日数据量如何估算?
- 为什么聚合最好保存 count、sum、min、max?
- 删除原始数据前要确认什么?
完成标准¶
- 能估算消息条数和存储量
- 能区分最新状态、原始和聚合数据
- 能设计三层保留策略
- 能解释设备时间与接收时间的差异
延伸阅读:Timescale Hypertables、Continuous Aggregates
下一单元:规则、告警与去重