TDengine 在智能制造领域的应用实践

TDengine 在智能制造领域的应用实践

一、概述

智能制造场景中,从生产设备采集的海量时序数据具有高频率、多维度、强关联的特点。TDengine 凭借其独特的"一台设备一张表"数据模型和高效的时序数据处理能力,成为智能制造领域的理想选择。本文将通过实际案例展示 TDengine 在智能制造中的数据建模、写入和查询实践。

二、场景分析

以某智能制造工厂的设备监控系统为例,需要采集和分析以下数据:

  • 生产设备监控:注塑机、数控机床、机器人等设备的运行状态
  • 环境监测:车间温湿度、气压、粉尘浓度等环境参数
  • 能耗管理:各生产线的电力、水、气等能源消耗
  • 质量检测:产品尺寸、重量、缺陷等质量指标

系统需要满足以下需求:

  1. 支持 10 万+ 数据采集点的实时数据接入
  2. 提供毫秒级的实时数据查询响应
  3. 支持多维度的设备状态分析和故障预警
  4. 实现生产过程的可视化追溯

三、数据建模实践

3.1 设备监控数据模型

方案一:多列模型(推荐)

采用多列模型将同一设备同时采集的多个物理量存储在一张表中,提高存储和查询效率。

sql 复制代码
-- 创建数据库,针对工业场景优化参数
CREATE DATABASE IF NOT EXISTS manufacture 
    BUFFER 256          -- 写入缓存 256MB
    CACHEMODEL 'both'   -- 同时缓存最新数据块和最新数据行
    CACHESIZE 64        -- 缓存大小 64MB
    DURATION 7          -- 数据文件存储时长 7 天
    KEEP 3650           -- 数据保留 10 年
    PAGES 256           -- VNODE 中元数据存储引擎的缓存页数
    PAGESIZE 4          -- VNODE 中元数据存储引擎的页大小 4KB
    PRECISION 'ms'      -- 时间精度为毫秒
    REPLICA 3           -- 数据副本数为 3
    WAL_LEVEL 1         -- WAL 级别为 1(异步落盘)
    WAL_RETENTION_PERIOD 3600;  -- WAL 保留 1 小时,支持数据订阅回放

-- 使用数据库
USE manufacture;

-- 创建注塑机监控超级表
CREATE STABLE IF NOT EXISTS injection_molding_machines (
    ts TIMESTAMP,                    -- 时间戳(主键,必须)
    status INT,                      -- 设备状态:0-停机, 1-运行, 2-故障, 3-维护
    temperature FLOAT,               -- 料筒温度(℃)
    pressure FLOAT,                  -- 注塑压力(MPa)
    speed INT,                       -- 螺杆转速(rpm)
    cycle_time INT,                  -- 成型周期(秒)
    shot_count BIGINT,               -- 累计射出次数
    energy_consumption FLOAT,        -- 瞬时能耗(kW)
    alarm_code INT                   -- 报警代码,0 表示无报警
) TAGS (
    machine_id VARCHAR(64),          -- 设备编号
    model VARCHAR(64),               -- 设备型号
    workshop VARCHAR(64),            -- 所属车间
    production_line VARCHAR(64),     -- 所属生产线
    install_date TIMESTAMP,          -- 安装日期
    rated_power FLOAT,               -- 额定功率(kW)
    location VARCHAR(128)            -- 安装位置
);

-- 创建环境监测超级表
CREATE STABLE IF NOT EXISTS environment_sensors (
    ts TIMESTAMP,
    temperature FLOAT,               -- 温度(℃)
    humidity FLOAT,                  -- 湿度(%)
    pressure FLOAT,                  -- 气压(kPa)
    pm25 FLOAT,                      -- PM2.5 浓度(μg/m³)
    pm10 FLOAT                       -- PM10 浓度(μg/m³)
) TAGS (
    sensor_id VARCHAR(64),
    sensor_type VARCHAR(32),
    area VARCHAR(64),
    floor INT
);

-- 创建能耗监测超级表
CREATE STABLE IF NOT EXISTS energy_meters (
    ts TIMESTAMP,
    voltage FLOAT,                   -- 电压(V)
    current FLOAT,                   -- 电流(A)
    power FLOAT,                     -- 功率(kW)
    power_factor FLOAT,              -- 功率因数
    energy_total DOUBLE,             -- 总电能(kWh)
    phase FLOAT                      -- 相位角(度)
) TAGS (
    meter_id VARCHAR(64),
    meter_location VARCHAR(128),
    device_type VARCHAR(64),
    group_id INT
);
方案二:单列模型

对于采集量种类频繁变化的场景,可采用单列模型:

sql 复制代码
-- 创建单列模型超级表(每个物理量单独一张表)
CREATE STABLE IF NOT EXISTS device_metrics (
    ts TIMESTAMP,
    value DOUBLE                     -- 统一的数值字段
) TAGS (
    device_id VARCHAR(64),
    metric_name VARCHAR(64),         -- 指标名称:temperature, pressure 等
    unit VARCHAR(32),                -- 单位
    data_type VARCHAR(32)            -- 数据类型:ANALOG, DIGITAL
);

3.2 创建子表

方式一:手动创建子表
sql 复制代码
-- 创建具体的注塑机子表
CREATE TABLE IF NOT EXISTS im_machine_001 
USING injection_molding_machines 
TAGS (
    'IM-001',                        -- machine_id
    'HT-2800',                       -- model
    '一车间',                         -- workshop
    '生产线A',                        -- production_line
    '2023-01-15 00:00:00',          -- install_date
    280.0,                           -- rated_power
    '一车间东区A03'                   -- location
);

CREATE TABLE IF NOT EXISTS im_machine_002 
USING injection_molding_machines 
TAGS (
    'IM-002', 'HT-2800', '一车间', '生产线A', 
    '2023-01-15 00:00:00', 280.0, '一车间东区A04'
);

-- 创建环境传感器子表
CREATE TABLE IF NOT EXISTS env_workshop1_zone1 
USING environment_sensors 
TAGS ('ENV-001', 'Temperature&Humidity', '一车间', 1);

-- 创建电表子表
CREATE TABLE IF NOT EXISTS meter_line_a 
USING energy_meters 
TAGS ('METER-A01', '一车间生产线A配电柜', '三相电表', 1);
方式二:自动建表(推荐)

在写入数据时自动创建子表,简化应用开发:

sql 复制代码
-- 写入数据时自动创建子表
INSERT INTO im_machine_003 
USING injection_molding_machines 
TAGS (
    'IM-003', 'HT-3500', '二车间', '生产线B',
    '2023-03-20 00:00:00', 350.0, '二车间西区B01'
)
VALUES (
    NOW, 1, 185.5, 120.8, 850, 45, 125680, 78.5, 0
);

3.3 数据模型对比

模型类型 适用场景 优点 缺点
多列模型 采集量固定、同时采集 写入效率高、存储效率高、查询方便 结构变更需修改表结构
单列模型 采集量动态变化 灵活性强、易于扩展 写入效率相对较低、查询需要关联

四、数据写入实践

4.1 SQL 方式写入

单条写入
sql 复制代码
-- 插入单条数据
INSERT INTO im_machine_001 VALUES (
    '2024-12-22 10:30:00.000',
    1,              -- status: 运行
    185.2,          -- temperature
    118.5,          -- pressure  
    820,            -- speed
    42,             -- cycle_time
    125345,         -- shot_count
    76.8,           -- energy_consumption
    0               -- alarm_code
);
批量写入(推荐)
sql 复制代码
-- 批量插入多条数据到同一张表
INSERT INTO im_machine_001 VALUES 
    ('2024-12-22 10:30:00.000', 1, 185.2, 118.5, 820, 42, 125345, 76.8, 0)
    ('2024-12-22 10:30:01.000', 1, 185.3, 118.6, 822, 42, 125346, 77.1, 0)
    ('2024-12-22 10:30:02.000', 1, 185.1, 118.4, 818, 43, 125347, 76.5, 0);

-- 批量插入数据到多张表(自动建表)
INSERT INTO 
    im_machine_001 VALUES ('2024-12-22 10:30:00', 1, 185.2, 118.5, 820, 42, 125345, 76.8, 0)
    im_machine_002 VALUES ('2024-12-22 10:30:00', 1, 186.1, 120.2, 835, 41, 98760, 82.3, 0)
    im_machine_003 USING injection_molding_machines 
        TAGS ('IM-003', 'HT-3500', '二车间', '生产线B', '2023-03-20 00:00:00', 350.0, '二车间西区B01')
        VALUES ('2024-12-22 10:30:00', 1, 192.5, 135.8, 920, 38, 67890, 95.2, 0);

4.2 参数绑定写入(高性能)

使用参数绑定可以显著提升写入性能,推荐用于高频数据写入场景。

Python 示例
python 复制代码
import taos
from datetime import datetime

def write_with_stmt():
    """使用参数绑定写入数据"""
    conn = taos.connect(database="manufacture")
    
    try:
        # 准备 SQL 语句,使用 ? 作为占位符
        sql = """INSERT INTO ? USING injection_molding_machines 
                 TAGS(?, ?, ?, ?, ?, ?, ?) 
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"""
        
        stmt = conn.statement(sql)
        
        # 准备数据
        machines = [
            {
                'table': 'im_machine_101',
                'tags': ('IM-101', 'HT-2800', '三车间', '生产线C', 
                        '2024-01-01 00:00:00', 280.0, '三车间C01'),
                'data': [
                    ('2024-12-22 10:30:00.000', 1, 185.2, 118.5, 820, 42, 125345, 76.8, 0),
                    ('2024-12-22 10:30:01.000', 1, 185.3, 118.6, 822, 42, 125346, 77.1, 0),
                    ('2024-12-22 10:30:02.000', 1, 185.1, 118.4, 818, 43, 125347, 76.5, 0),
                ]
            },
            {
                'table': 'im_machine_102',
                'tags': ('IM-102', 'HT-3500', '三车间', '生产线C',
                        '2024-01-01 00:00:00', 350.0, '三车间C02'),
                'data': [
                    ('2024-12-22 10:30:00.000', 1, 192.5, 135.8, 920, 38, 67890, 95.2, 0),
                    ('2024-12-22 10:30:01.000', 1, 192.6, 135.9, 921, 38, 67891, 95.3, 0),
                ]
            }
        ]
        
        # 绑定并写入数据
        for machine in machines:
            # 设置表名和标签
            tags = taos.new_bind_params(7)  # 7 个标签
            tags[0].binary(machine['tags'][0])    # machine_id
            tags[1].binary(machine['tags'][1])    # model
            tags[2].binary(machine['tags'][2])    # workshop
            tags[3].binary(machine['tags'][3])    # production_line
            tags[4].timestamp(machine['tags'][4]) # install_date
            tags[5].float(machine['tags'][5])     # rated_power
            tags[6].binary(machine['tags'][6])    # location
            
            stmt.set_tbname_tags(machine['table'], tags)
            
            # 绑定数据行
            for row in machine['data']:
                values = taos.new_bind_params(9)  # 9 列数据
                values[0].timestamp(row[0])
                values[1].int(row[1])
                values[2].float(row[2])
                values[3].float(row[3])
                values[4].int(row[4])
                values[5].int(row[5])
                values[6].bigint(row[6])
                values[7].float(row[7])
                values[8].int(row[8])
                
                stmt.bind_param(values)
        
        # 执行写入
        stmt.execute()
        print(f"成功写入 {sum(len(m['data']) for m in machines)} 条数据")
        
    finally:
        stmt.close()
        conn.close()

if __name__ == '__main__':
    write_with_stmt()

4.3 无模式写入(InfluxDB 行协议)

适用于从其他时序数据库迁移的场景:

python 复制代码
import taos

def write_with_schemaless():
    """使用无模式写入(InfluxDB 行协议)"""
    conn = taos.connect(database="manufacture")
    
    # InfluxDB 行协议格式
    lines = [
        "injection_molding_machines,machine_id=IM-201,model=HT-2800,workshop=四车间 "
        "status=1i,temperature=185.2,pressure=118.5,speed=820i,cycle_time=42i,"
        "shot_count=125345i,energy_consumption=76.8,alarm_code=0i 1703232600000",
        
        "injection_molding_machines,machine_id=IM-202,model=HT-3500,workshop=四车间 "
        "status=1i,temperature=192.5,pressure=135.8,speed=920i,cycle_time=38i,"
        "shot_count=67890i,energy_consumption=95.2,alarm_code=0i 1703232600000",
    ]
    
    try:
        conn.schemaless_insert(
            lines,
            taos.SmlProtocol.LINE_PROTOCOL,
            taos.SmlPrecision.MILLISECONDS
        )
        print(f"成功写入 {len(lines)} 条数据")
    finally:
        conn.close()

4.4 高性能批量写入实践

对于高并发场景,可以使用多线程/多进程写入:

python 复制代码
import taos
import multiprocessing
from queue import Queue, Empty
import time

WRITE_TASK_COUNT = 4      # 写入任务数
MAX_BATCH_SIZE = 3000     # 每批次最大行数

def run_write_task(task_id: int, queue: Queue):
    """写入任务"""
    conn = taos.connect(database="manufacture")
    
    try:
        while True:
            lines = []
            # 批量获取数据
            for _ in range(MAX_BATCH_SIZE):
                try:
                    line = queue.get_nowait()
                    if line == 'DONE':
                        return
                    lines.append(line)
                except Empty:
                    time.sleep(0.01)
                    break
            
            if lines:
                # 拼接 SQL
                sql = "INSERT INTO " + " ".join(lines)
                conn.execute(sql)
                print(f"Task {task_id}: 写入 {len(lines)} 条")
    finally:
        conn.close()

def fast_write_demo():
    """高性能写入示例"""
    queue = multiprocessing.Queue(maxsize=100000)
    
    # 启动写入进程
    processes = []
    for i in range(WRITE_TASK_COUNT):
        p = multiprocessing.Process(target=run_write_task, args=(i, queue))
        p.start()
        processes.append(p)
    
    # 模拟数据生成
    for i in range(10000):
        line = f"im_machine_001 VALUES (NOW+{i}a, 1, 185.2, 118.5, 820, 42, {125345+i}, 76.8, 0)"
        queue.put(line)
    
    # 发送结束信号
    for _ in range(WRITE_TASK_COUNT):
        queue.put('DONE')
    
    # 等待完成
    for p in processes:
        p.join()
    
    print("批量写入完成")

if __name__ == '__main__':
    fast_write_demo()

五、数据查询实践

5.1 基础查询

查询最新数据
sql 复制代码
-- 查询单台设备最新状态
SELECT LAST(*) FROM im_machine_001;

-- 查询所有设备最新状态
SELECT LAST_ROW(*) FROM injection_molding_machines 
PARTITION BY tbname;

-- 查询指定车间所有设备最新状态
SELECT tbname, LAST_ROW(ts, status, temperature, pressure, alarm_code)
FROM injection_molding_machines
WHERE workshop = '一车间'
PARTITION BY tbname;
时间范围查询
sql 复制代码
-- 查询某设备过去1小时的数据
SELECT ts, status, temperature, pressure, energy_consumption
FROM im_machine_001
WHERE ts >= NOW - 1h;

-- 查询指定时间范围的故障记录
SELECT ts, machine_id, alarm_code, temperature, pressure
FROM injection_molding_machines
WHERE ts BETWEEN '2024-12-22 00:00:00' AND '2024-12-22 23:59:59'
  AND alarm_code > 0
ORDER BY ts DESC;

5.2 聚合查询

基础聚合
sql 复制代码
-- 统计设备运行时长(小时)
SELECT 
    machine_id,
    COUNT(*) / 3600 AS run_hours,
    AVG(temperature) AS avg_temp,
    AVG(energy_consumption) AS avg_power,
    SUM(energy_consumption) / 3600 AS total_energy_kwh
FROM injection_molding_machines
WHERE ts >= NOW - 1d
  AND status = 1  -- 运行状态
GROUP BY machine_id;

-- 统计各车间设备数量和平均能耗
SELECT 
    workshop,
    COUNT(DISTINCT machine_id) AS machine_count,
    AVG(energy_consumption) AS avg_power
FROM injection_molding_machines
WHERE ts >= NOW - 1h
GROUP BY workshop;

5.3 窗口查询(降采样)

窗口查询是工业场景中最常用的功能,用于将高频采集数据降采样为低频统计数据。

时间窗口(INTERVAL)
sql 复制代码
-- 按 10 分钟统计设备平均参数
SELECT 
    _wstart AS window_start,
    _wend AS window_end,
    AVG(temperature) AS avg_temp,
    AVG(pressure) AS avg_pressure,
    AVG(speed) AS avg_speed,
    AVG(energy_consumption) AS avg_power
FROM im_machine_001
WHERE ts >= NOW - 1d
INTERVAL(10m);

-- 按小时统计各生产线产量和能耗
SELECT 
    _wstart AS hour,
    production_line,
    SUM(shot_count) - MIN(shot_count) AS output_count,
    SUM(energy_consumption) / 3600 AS total_energy_kwh
FROM injection_molding_machines
WHERE ts >= NOW - 1d
PARTITION BY production_line
INTERVAL(1h);

-- 按天统计设备 OEE(设备综合效率)
SELECT 
    _wstart AS date,
    machine_id,
    -- 时间开动率
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS availability,
    -- 平均周期时间(性能开动率的基础)
    AVG(CASE WHEN status = 1 THEN cycle_time ELSE NULL END) AS avg_cycle_time,
    -- 产量
    MAX(shot_count) - MIN(shot_count) AS daily_output
FROM injection_molding_machines
WHERE ts >= NOW - 7d
PARTITION BY machine_id
INTERVAL(1d);
滑动窗口
sql 复制代码
-- 计算过去 5 分钟的移动平均(每分钟更新一次)
SELECT 
    _wstart,
    machine_id,
    AVG(temperature) AS avg_temp,
    MAX(pressure) AS max_pressure
FROM injection_molding_machines
WHERE ts >= NOW - 1h
PARTITION BY machine_id
INTERVAL(1m) SLIDING(1m);
会话窗口(SESSION)

适用于分析设备连续运行/停机时段:

sql 复制代码
-- 统计设备连续运行时段
SELECT 
    _wstart AS session_start,
    _wend AS session_end,
    _wduration / 1000 AS duration_seconds,
    AVG(temperature) AS avg_temp,
    AVG(energy_consumption) AS avg_power
FROM im_machine_001
WHERE ts >= NOW - 1d
  AND status = 1
SESSION(ts, 5m);  -- 间隔超过 5 分钟视为新会话
状态窗口(STATE)

统计设备不同状态的持续时间:

sql 复制代码
-- 统计设备各状态持续时长
SELECT 
    _wstart,
    _wend,
    _wduration / 1000 AS duration_seconds,
    status,
    CASE status
        WHEN 0 THEN '停机'
        WHEN 1 THEN '运行'
        WHEN 2 THEN '故障'
        WHEN 3 THEN '维护'
    END AS status_name
FROM im_machine_001
WHERE ts >= NOW - 1d
STATE_WINDOW(status);

5.4 插值查询

用于生成固定时间间隔的报表数据:

sql 复制代码
-- 每 10 分钟采样一次(线性插值)
SELECT 
    _irowts AS sample_time,
    INTERP(temperature) AS temp,
    INTERP(pressure) AS pressure,
    INTERP(energy_consumption) AS power
FROM im_machine_001
WHERE ts >= '2024-12-22 00:00:00' 
  AND ts < '2024-12-23 00:00:00'
RANGE('2024-12-22 00:00:00', '2024-12-23 00:00:00') 
EVERY(10m)
FILL(LINEAR);

-- 截面查询:获取特定时间点的数据快照
SELECT 
    tbname AS machine,
    INTERP(*) 
FROM injection_molding_machines
WHERE workshop = '一车间'
  AND ts >= '2024-12-22 10:00:00' 
  AND ts < '2024-12-22 10:10:00'
RANGE('2024-12-22 10:00:00') 
PARTITION BY tbname
FILL(VALUE, 0);

5.5 多表关联查询

JOIN 查询
sql 复制代码
-- 关联设备数据和能耗数据
SELECT 
    m.ts,
    m.machine_id,
    m.status,
    m.energy_consumption AS instant_power,
    e.power AS meter_power,
    e.energy_total
FROM im_machine_001 m
LEFT JOIN meter_line_a e ON m.ts = e.ts
WHERE m.ts >= NOW - 1h;

-- 三表关联:设备+环境+能耗
SELECT 
    m._wstart,
    AVG(m.temperature) AS machine_temp,
    AVG(env.temperature) AS ambient_temp,
    AVG(m.energy_consumption) AS power,
    SUM(e.energy_total) AS total_energy
FROM injection_molding_machines m,
     environment_sensors env,
     energy_meters e
WHERE m.workshop = '一车间'
  AND env.area = '一车间'
  AND e.meter_location LIKE '一车间%'
  AND m.ts >= NOW - 1d
  AND env.ts >= NOW - 1d
  AND e.ts >= NOW - 1d
INTERVAL(1h);

5.6 高级分析查询

故障预警分析
sql 复制代码
-- 检测温度异常(连续 5 分钟超过阈值)
SELECT 
    tbname AS machine,
    machine_id,
    _wstart,
    _wend,
    AVG(temperature) AS avg_temp,
    MAX(temperature) AS max_temp
FROM injection_molding_machines
WHERE ts >= NOW - 1h
  AND temperature > 200  -- 温度阈值
PARTITION BY tbname
INTERVAL(5m)
HAVING AVG(temperature) > 200;

-- 连续过载报警(能耗超过额定功率 1.2 倍)
SELECT 
    machine_id,
    rated_power,
    _wstart,
    _wduration / 1000 AS overload_seconds,
    AVG(energy_consumption) AS avg_power
FROM injection_molding_machines
WHERE ts >= NOW - 1d
  AND energy_consumption > rated_power * 1.2
PARTITION BY machine_id
STATE_WINDOW(energy_consumption > rated_power * 1.2);
产能统计分析
sql 复制代码
-- 统计各生产线日产量和合格率
SELECT 
    _wstart AS date,
    production_line,
    MAX(shot_count) - MIN(shot_count) AS daily_output,
    -- 故障停机次数
    COUNT(CASE WHEN alarm_code > 0 THEN 1 END) AS fault_count,
    -- 平均周期时间
    AVG(CASE WHEN status = 1 THEN cycle_time END) AS avg_cycle
FROM injection_molding_machines
WHERE ts >= NOW - 30d
PARTITION BY production_line
INTERVAL(1d);

-- 设备稼动率分析
SELECT 
    machine_id,
    workshop,
    -- 总时间(小时)
    (MAX(ts) - MIN(ts)) / 3600000 AS total_hours,
    -- 运行时间(小时)
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) / 3600 AS run_hours,
    -- 稼动率
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS utilization_rate
FROM injection_molding_machines
WHERE ts >= NOW - 7d
GROUP BY machine_id, workshop
ORDER BY utilization_rate DESC;
能耗分析
sql 复制代码
-- 各车间能耗排名
SELECT 
    workshop,
    SUM(energy_consumption) / 3600 AS total_energy_kwh,
    AVG(energy_consumption) AS avg_power_kw,
    MAX(energy_consumption) AS peak_power_kw
FROM injection_molding_machines
WHERE ts >= NOW - 1d
GROUP BY workshop
ORDER BY total_energy_kwh DESC;

-- 能耗趋势分析(按小时)
SELECT 
    _wstart AS hour,
    production_line,
    SUM(energy_consumption) / 3600 AS energy_kwh,
    MAX(shot_count) - MIN(shot_count) AS output,
    -- 单位产品能耗
    SUM(energy_consumption) / NULLIF(MAX(shot_count) - MIN(shot_count), 0) AS energy_per_unit
FROM injection_molding_machines
WHERE ts >= NOW - 1d
PARTITION BY production_line
INTERVAL(1h);

5.7 实时流计算

使用流计算实现实时降采样和预警:

sql 复制代码
-- 创建实时降采样流(每分钟聚合)
CREATE STREAM IF NOT EXISTS stream_machine_1min INTO machine_stats_1min AS
SELECT 
    _wstart AS ts,
    machine_id,
    AVG(temperature) AS avg_temp,
    AVG(pressure) AS avg_pressure,
    AVG(speed) AS avg_speed,
    AVG(energy_consumption) AS avg_power,
    MAX(alarm_code) AS max_alarm
FROM injection_molding_machines
PARTITION BY machine_id
INTERVAL(1m);

-- 创建实时异常检测流
CREATE STREAM IF NOT EXISTS stream_machine_alert INTO machine_alerts AS
SELECT 
    _wstart AS ts,
    machine_id,
    workshop,
    AVG(temperature) AS avg_temp,
    MAX(alarm_code) AS alarm_code
FROM injection_molding_machines
WHERE temperature > 200 OR alarm_code > 0
PARTITION BY machine_id
INTERVAL(5m);

-- 查询流计算结果
SELECT * FROM machine_stats_1min 
WHERE ts >= NOW - 1h
ORDER BY ts DESC;

六、性能优化建议

6.1 数据库参数优化

sql 复制代码
-- 针对高频写入场景优化
ALTER DATABASE manufacture 
    BUFFER 512          -- 增大写入缓存
    WAL_LEVEL 1         -- 异步落盘提升写入性能
    WAL_FSYNC_PERIOD 1000;  -- WAL 刷盘周期 1 秒

-- 针对查询优化
ALTER DATABASE manufacture 
    CACHEMODEL 'both'   -- 同时缓存数据块和行
    CACHESIZE 128;      -- 增大缓存

6.2 查询优化

sql 复制代码
-- 使用标签过滤(高效)
SELECT * FROM injection_molding_machines
WHERE workshop = '一车间'  -- 标签过滤,走元数据索引
  AND ts >= NOW - 1h;

-- 避免全表扫描
SELECT * FROM injection_molding_machines
WHERE temperature > 200  -- 数据列过滤,需要扫描数据
LIMIT 100;               -- 使用 LIMIT 限制结果集

-- 使用分区查询
SELECT machine_id, AVG(temperature)
FROM injection_molding_machines
WHERE ts >= NOW - 1d
PARTITION BY machine_id;  -- 按子表分区并行查询

6.3 写入优化

  1. 批量写入:每批 1000-5000 条记录
  2. 使用参数绑定:比普通 SQL 快 5-10 倍
  3. 多线程并发写入:充分利用多核 CPU
  4. 合理设置 BUFFER:写入缓存设为内存的 1/4 到 1/2

七、实际案例总结

某烟厂项目实施效果:

  • 数据规模:累计存储超过 2 万亿条数据
  • 查询性能:最新数据查询延迟 < 10ms
  • 写入性能:支持 10 万+ 测点的实时数据接入
  • 存储效率:相比传统数据库,存储空间节省 80%
  • 稳定性:系统持续稳定运行超过 2 年

关键技术点:

  1. 采用"一台设备一张表"的数据模型
  2. 使用参数绑定批量写入提升性能
  3. 通过流计算实现实时降采样
  4. 利用标签进行多维度分析
  5. 配置 WAL 保留支持数据订阅回放

八、总结

TDengine 在智能制造领域具有以下核心优势:

  1. 灵活的数据模型:支持多列/单列模型,适应不同场景
  2. 高效的写入性能:支持批量写入、参数绑定、多线程并发
  3. 强大的查询能力:窗口查询、插值查询、流计算等时序特性
  4. 简化的运维管理:自动分区、动态扩容、高可用集群
  5. 完善的生态支持:丰富的数据采集器、可视化工具对接

通过合理的数据建模和性能优化,TDengine 能够有效支撑智能制造场景中海量时序数据的存储、分析和应用,为企业数字化转型提供坚实的数据底座。

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
Coder_Boy_2 小时前
基于 MQTT 的单片机与 Java 业务端双向通信全流程
java·单片机·嵌入式硬件
山沐与山2 小时前
【Flink】Flink算子大全
大数据·flink
Asurplus2 小时前
Centos7安装Maven环境
java·centos·maven·apache·yum
想学后端的前端工程师2 小时前
【Spring Boot微服务开发实战:从入门到企业级应用】
java·开发语言·python
男孩李2 小时前
浅谈PostgreSQL 模式(SCHEMA)
数据库·postgresql
TG:@yunlaoda360 云老大2 小时前
如何在华为云国际站代理商控制台进行基础状态核查的常见问题解答
数据库·华为云·php
徐老总2 小时前
手机号脱敏处理(Python/Scala 双版本实现)
java
ayingmeizi1632 小时前
智慧养老的数字化转型:AI CRM如何重构全链路增长
大数据·人工智能·重构
夏末4722 小时前
面试必问!多线程操作集合避坑指南:用synchronized搞定线程安全
java