tdenginee维护
先对齐你的架构模式总结
整体架构:
16 张【单指标超级表 STable】:一指标一张 STable,ts + val + sn标签
每个设备 SN,预先手动创建独立子表(例如 stb_d1001、bat_d1001)
meters_v:虚拟模板超级表(VIRTUAL 1),作为宽表 Schema 定义
d1001_v:VTABLE 虚拟宽表,关联该设备所有指标物理子表,对外提供统一宽口径查询
架构核心:物理存储窄表(一指标一表),查询层虚拟宽表屏蔽多表关联
适配 TDengine 企业版 VTABLE 跨子表映射特性。
下面依次回答你 3 个核心问题,结合 Stihl 割草机 IoT 业务(波动流量:高频上报 + 低频历史查询)。
1、后续新增指标(字段)如何优雅扩展
当前现状
新增业务指标 = 新增一张单指标 STable → 创建设备子表 → 修改模板meters_v → 修改所有设备 VTABLE 映射定义。
原生流程很重,必须标准化流程
标准扩展步骤(生产规范)
步骤 1:新建指标超级表
sql
CREATE STABLE IF NOT EXISTS stihl_new_xxx_stb (ts TIMESTAMP, val DOUBLE) TAGS(sn BINARY(64));
步骤 2:为已有设备创建对应子表
sql
CREATE TABLE newxxx_d1001 USING stihl_new_xxx_stb(sn) TAGS("d1001");
步骤 3:修改虚拟模板 meters_v 增加列
sql
ALTER STABLE meters_v ADD COLUMN new_xxx DOUBLE;
⚠️关键限制:已经创建的 VTABLE 不会自动同步新增字段!
步骤 4:重建所有设备 VTABLE(二选一方案)
方案 A(存量设备少,推荐)
sql
DROP VTABLE IF EXISTS d1001_v;
CREATE VTABLE d1001_v (
dev_status FROM stb_d1001.val,
map_sub_status FROM mappingstb_d1001.val,
......
new_xxx FROM newxxx_d1001.val
) USING meters_v TAGS (2);
方案 B(设备量巨大,不想重建 VTABLE)
上层应用做兼容:新指标独立查询,不纳入 VTABLE,新项目设备直接在建 VTABLE 时带上新字段。
优化建议【优雅方案】
前期预留扩展字段不可行,窄表架构天生新增指标就要新增表;
新增设备自动化:Java 代码封装工具类,新 SN 上线自动批量创建所有指标子表,自动生成 VTABLE,杜绝手工执行 SQL;
指标尽量收敛,不要随意新增;区分【实时状态指标】和【历史统计指标】,统计类指标不要走这套窄表架构。
避坑:
不要尝试 ALTER VTABLE,TDengine 企业版不支持修改 VTABLE 字段映射关系,只能删了重建。
2、设备数据如何查询(两种查询方式)
方式 1:业务推荐方式【查询 VTABLE 虚拟宽表】(上层应用首选)
对外屏蔽底层多张物理表,一条 SQL 获取全部指标
sql
SELECT ts,dev_status,fault_code,battery_soc
FROM d1001_v
WHERE ts >= NOW() - 24h
ORDER BY ts ASC;
-- 查询最新一条实时状态
SELECT LAST(*) FROM d1001_v;
方式 2:直接查询底层物理子表(排查问题、补数场景)
sql
-- 单独查询设备状态
SELECT ts,val FROM stb_d1001 WHERE ts >= NOW() -1h;
-- 单独查询电量
SELECT ts,val FROM bat_d1001 WHERE ts >= NOW() -1h;
重要查询约束
VTABLE 底层自动关联多张子表,依赖时间戳 ts 对齐;
如果同一上报批次指标时间戳不一致,出现 NULL 空值;
过滤条件优先带上时间范围,时序数据库禁止无时间范围全表扫描;
LAST(*) 查询最新设备状态,IoT 业务高频使用,性能良好;
不支持跨 SN 查询:每个 VTABLE 绑定单一设备,多设备循环查询各自 VTABLE。
如果你需要批量多设备汇总分析,这套 VTABLE 模式不适合,需要 CQ 合并宽表方案。
3、该架构优缺点 + 波动流量(时而高频 / 时而低频)适配要点
架构总结
物理:一指标一张独立子表;查询:VTABLE 合成宽表
✅优点
写入隔离性极强
不同指标上报互不影响。例如:故障码高频秒级上报、电量 5 分钟上报,互相 IO 隔离。某指标写入压力暴涨不会挤占其他指标。非常适配割草机差异化上报频率场景。
存储弹性
不需要上报的指标无数据,不会产生空字段存储,节省磁盘;
冷热数据分离友好
后续可以单独对某些指标设置不同数据保留策略(需要企业版多级存储);
权限精细化
可以控制某些业务只能读取电量表,不能读取故障表;
应用层友好:上层只操作 VTABLE,SQL 语义和普通宽表一致,学习成本低。
❌缺点(重点风险)
元数据膨胀
每台设备 = N 张子物理表 + 1 张 VTABLE。设备上千台后,表数量爆炸,元数据管理压力上升;
新增指标运维成本高
新增指标必须重建全部存量设备 VTABLE,运维工作量大;
多指标查询存在底层关联开销
查询 VTABLE 等价后台多表 JOIN。时间范围越大,性能衰减越明显。
实时查询(近 1 小时)性能优秀;跨月大范围历史查询性能较差。
无法原生支持跨设备批量聚合
VTABLE 绑定单设备,不能一条 SQL 批量查询 100 台设备。
4、高低频波动场景【增删改查注意事项】
写入(INSERT)
写入只能写底层物理子表,禁止写入 VTABLE!VTABLE 只读
sql
--正确:写入物理子表
INSERT INTO stb_d1001 VALUES(NOW(),1);
--错误:不能insert into d1001_v
尽量同一上报报文统一 ts 时间戳!保证 VTABLE 查询时数据对齐,避免大量 null;
高频上报场景:开启批量写入,Java 客户端批量 insert,减少网络交互;
不要频繁写入完全相同数值(设备状态不变尽量不上报,边缘端消峰)。
查询(SELECT)
实时监控(高频查询):优先 LAST(*) 查询最新点,性能最优;
历史轨迹(低频查询):缩小时间窗口,避免跨数月大范围查询;大范围查询建议切换直查物理表;
不要使用 SELECT *,显式指定业务需要的字段,减少关联开销;
更新、删除(TDengine 时序特性)
TDengine 3.x 时序数据不鼓励 UPDATE,尽量采用追加写入模式;
删除:尽量使用按时间范围删除,避免单行删除;
sql
DELETE FROM stb_d1001 WHERE ts < '2026-01-01';
运维风险点
设备注销退役:需要同步删除该设备所有物理子表 + VTABLE,否则元数据持续堆积;
重启 TDengine 服务后,大量 VTABLE 首次查询会有短暂加载延迟;
备份恢复:需要保证【模板 meters_v、所有物理子表、VTABLE】元数据完整恢复。
5、给你 Stihl 项目最终架构建议
设备数量 <300 台:当前架构完全可行,满足割草机高低频混合上报,实时状态查询流畅;
设备数量 >800 台:强烈预留备选方案,后期切换【CQ 持续查询合并宽超级表】,放弃大量 VTABLE;
业务分层:
实时状态展示:使用 VTABLE(当前方案)
后台大数据统计、报表:独立任务消费 Kafka,预聚合写入 ClickHouse/TD 宽表,不要依赖 VTABLE 做统计;
如果你需要,我可以输出一份:
Java 自动化脚本伪代码(新设备 SN 上线,自动生成所有 CREATE TABLE 子表 + CREATE VTABLE SQL)。
浙公网安备 33010602011771号