设备数据为什么要有时序库
传感器数据的本质是「按时间顺序不断追加的数值流」:每秒一条,几百台设备持续写,一年就是上亿行。用普通关系数据库存这种数据,写入吞吐和按时间范围查询都会很快成为瓶颈。时序数据库(如 InfluxDB)就是为「高写入、按时间索引、按时间聚合」这个场景专门设计的。
时序库不擅长存复杂的关联查询,但在「某台设备最近 24 小时温度曲线」这类问题上,它又快又省。
- 写入时序库针对批量追加做了压缩与批写优化。
- 存储同类数值按列压缩,体积小一个数量级。
- 聚合内置按时间窗口的降采样与聚合函数。
- 保留支持自动过期策略,老数据自动归档或删除。
数据建模:标签、字段与时间戳
时序数据的结构很简单:一个测量名(measurement)、若干标签(tag)、若干字段(field)和一个时间戳。标签是「用来分组和筛选」的维度,比如设备编号、区域;字段是「被测量的数值」,比如温度、湿度。区别在于标签会被索引,字段不会——把高频变化的量放进标签,索引会爆炸。
// 一条写入:measurement = env, tag = dev, field = t/h
env,dev=room_a t=25.3,h=48.2 1728806400000000000
// ↑测量 ↑标签 ↑字段 ↑纳秒时间戳
建模的经验法则是:维度(设备、地点、类型)放标签,指标数值放字段。时间戳由上报端或网关统一对齐,避免每块板子用各自不准的本地时钟。
写入与降采样策略
直接把原始高频数据全部长期保留,成本会随设备数线性上涨。成熟的做法是分层:原始数据短期保留(比如 7 天),按分钟或小时聚合后的均值、峰值长期保留。这样既能随时回看最近的细节,又能用历史趋势做长期分析。
- 原始层1 秒粒度,保留 7 天,用于排障。
- 分钟层1 分钟均值,保留 90 天。
- 小时层1 小时均值/极值,保留 1 年以上。
- 聚合用连续查询自动把高层结果写到低层。
写入时还要注意批量化:网关把短时间内的多条数据攒成一批再写,比逐条写高效得多;同时对同一时间戳的重复数据做去重,防止设备补传造成重复点。
聚合查询与告警规则
看板上的曲线几乎都不是原始点,而是聚合结果:最近一小时按 1 分钟取平均,最近一天按 10 分钟取平均。这样点数从几千降到几十个,图表平滑又不丢趋势。查询时指定时间窗口和聚合函数即可。
// 查 room_a 最近 24 小时、按 10 分钟聚合的平均温度
SELECT mean(t) FROM env
WHERE dev='room_a' AND time > now() - 24h
GROUP BY time(10m);
告警规则是数据最有价值的用法之一:温度持续超过阈值、设备掉线超过几分钟,就触发通知。把告警建立在「聚合后的数据」上而不是原始点上,可以避免单次毛刺就误报。告警通道可对接前面讲过的订阅消息或短信,形成闭环。
可视化大屏的搭建思路
大屏不是把所有曲线堆上去,而是按「决策者关心什么」分区:顶部是总览指标(在线设备数、今日告警数),中部是核心趋势曲线,下部是分设备或分区域的对比。配色统一、留白克制,避免一屏塞满让人无从看起。
- 趋势类用折线,对比类用柱状,占比类用环形或饼图,别混用。
- 单位和时间范围要在图表上标明,看图的人不用猜。
- 关键告警用颜色突出,让异常一眼可见。
工具上,Grafana 这类可视化平台能直接连时序库、拖拽建面板、设置刷新间隔,是物联网大屏最省事的起点;需要深度定制交互时,再用前端图表库自己写。
数据治理与常见坑
第一个坑是标签基数失控:把设备编号这种每个设备都不同、且数量很大的值当标签,索引会随设备数膨胀。正确做法是设备编号做标签(因为要按设备筛选),但不要再叠加更多高基数维度。第二个坑是时区混乱,查询窗口和图表都要明确时区,否则「昨天 24 小时」会对不上。
第三个坑是只存数据不做质量校验。设备偶尔会上报明显不合理的值(温度 -500 度),这些脏点直接进库会污染曲线和告警。在网关层加一层范围校验,异常值丢弃或标记,比事后清洗便宜得多。
// 网关侧简单的合理性校验
if (t < -40 || t > 85) {
dropPoint(reason: 'out_of_range');
return;
}
小结与延伸阅读
物联网数据分析的主线是:把高频数值流进时序库,按时间分层降采样,用聚合查询驱动曲线与告警,最后用一屏看板把关键信号推到决策者眼前。数据本身不产生价值,被看见、被响应才产生价值。
- 设备端怎么采、怎么传,读《ESP32 智能硬件接入实战》。
- 通信链路打底,接《MQTT 协议详解与实战》。
- 平台侧的物模型与规则引擎,看《物联网平台选型与接入实践》。