标签:#TDengine #时序数据库 #SpringBoot #工控存储 #工业物联网

一、前言

前面三篇连载我们已经完整实现了工控后端三大核心采集能力:

  1. Modbus TCP:传统 PLC 轮询采集
  2. OPC-UA:智能设备订阅采集
  3. MQTT:物联网网关无线上报采集

设备数据源源不断秒级上报,点位量动辄几万、几十万。

很多新手项目死在最后一步:存储。

如果直接用 MySQL 存工控时序数据,会出现四大致命问题:

  • 秒级高频写入导致数据库锁等待、入库拥堵
  • 历史曲线查询超时、页面加载空白
  • 单表数据量爆炸,索引失效
  • 磁盘占用极高,运维压力巨大

工业项目标准解决方案:

业务数据用 MySQL,时序采集数据全部用 TDengine。

本文给大家一套可直接投产、工业标准化的 Spring Boot + TDengine 完整存储方案。

二、为什么工控项目必须用时序数据库?

1. 时序数据特点

  • 数据写入:只新增、几乎不修改、不删除
  • 数据量:秒级产生、海量累加
  • 查询场景:按时间范围查曲线、查历史、查统计

2. TDengine 工业优势(吊打 MySQL)

  • 写入性能提升 10 倍+,支持海量设备并发上报
  • 数据压缩比 10:1,极大节省服务器磁盘
  • 自带时序索引,曲线查询秒出
  • 专门适配工控、物联网、SCADA 场景
  • 开源免费、部署简单、离线可用

三、完整项目依赖

<!-- TDengine 官方驱动 -->
<dependency>
    <groupId>com.taosdata</groupId>
    <artifactId>taos-jdbcdriver</artifactId>
    <version>3.0.6</version>
</dependency>

四、application.yml 工业级配置

适配内网离线部署、适配高并发写入

spring:
  datasource:
    tdengine:
      driver-class-name: com.taosdata.jdbc.TSDBDriver
      url: jdbc:TAOS://127.0.0.1:6030/industrial_scada_db
      username: root
      password: taos123456

五、工控标准建库、建超级表(核心规范)

TDengine 最关键的就是超级表 + 子表架构,一个设备一张子表,统一超级表模板。

1. 创建数据库

CREATE DATABASE IF NOT EXISTS industrial_scada_db;

2. 创建工控通用超级表

CREATE STABLE IF NOT EXISTS device_collect_data (
    ts TIMESTAMP,
    value DOUBLE,
    status TINYINT
) TAGS (
    device_id BINARY(32),
    device_type BINARY(20)
);

字段说明(工业标准)

  • ts:采集时间戳(时序主键)
  • value:设备采集数值(温度、压力、电流、电压等)
  • status:设备状态 0 正常 1 异常 2 离线
  • device_id:设备唯一编号
  • device_type:设备类型(PLC/传感器/仪表)

六、Spring Boot 通用入库工具类(可直接投产)

适配 Modbus、OPC-UA、MQTT 所有采集数据统一入库

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

/**
 * TDengine 工业时序数据工具类
 * 适配 SCADA、物联网、轨交监控数据存储
 */
@Component
public class TdEngineDataUtil {

    @Resource
    private JdbcTemplate tdJdbcTemplate;

    /**
     * 单条设备采集数据入库
     * @param subTableName 设备子表名
     * @param ts 时间戳
     * @param value 采集数值
     * @param status 设备状态
     * @param deviceId 设备编号
     * @param deviceType 设备类型
     */
    public void insertDeviceData(String subTableName, long ts, double value, int status,
                                 String deviceId, String deviceType) {
        String sql = "INSERT INTO " + subTableName + " USING device_collect_data " +
                "TAGS(?,?) VALUES(?,?,?)";
        tdJdbcTemplate.update(sql, deviceId, deviceType, ts, value, status);
    }
}

七、批量入库优化(工业现场必用)

单条写入压力大,工业项目必须批量写入

// 伪代码逻辑(项目直接用)
// 1、MQTT/OPC/Modbus 采集数据 → 存入本地队列
// 2、队列攒满 100 条 / 50ms 超时 → 批量 insert
// 3、大幅降低数据库 IO,解决卡顿

八、历史曲线查询实战(前端大屏必备)

按时间范围查询设备历史数据,用于前端曲线回放

SELECT ts, value, status FROM device_collect_data 
WHERE device_id = 'PLC_001' 
AND ts > NOW() - 1 HOUR;

九、完整工控项目闭环架构(终极版)

经过 4 篇连载,你现在拥有完整工业落地架构:

1. 采集层

Modbus + OPC-UA + MQTT 三协议全覆盖

2. 存储层

MySQL(业务配置数据)
TDengine(海量时序采集数据)

3. 服务层

Spring Boot 分层架构、容错、重连、异步削峰

4. 展示层

WebSocket 实时推送 + 大屏曲线展示

这套架构可以直接对标市面 90% 商用 SCADA 平台。

十、现场高频踩坑总结

1. 时序数据量太大,磁盘爆满

解决:TDengine 设置数据过期策略,自动清理冷数据、自动归档

2. 单设备频繁建表卡顿

解决:设备首次采集建表、后续复用子表,避免频繁 DDL

3. 直接查全量数据页面卡死

解决:必须带时间范围查询,禁止无条件全表查

4. 写入频繁超时

解决:内存队列异步批量写入,禁止同步单条高频写入

十一、结尾

普通 Java 开发拼 CRUD,工控 Java 拼架构、拼协议、拼存储、拼稳定性。

吃透这四篇连载:
Modbus → OPC-UA → MQTT → TDengine

你已经具备独立开发工业监控平台的能力。

下一篇连载:工控告警规则引擎实战(越限告警、延时告警、分级推送),补齐工业项目最后一块核心短板。

更多推荐