一、背景
在数据中台时序数据接入过程中,不同测点的数据类型虽然不同,但设备、区域、系统、点位等业务属性基本一致。
因此可以采用 TDengine 超级表统一建模:
时间字段 + 数据值 + 质量码 + 固定业务 TAG本项目约定所有超级表统一采用:
time val quality 21 个标准 TAG不同类型超级表之间,主要区别是:
超级表名称 val 字段的数据类型其余 TAG:
字段名称 字段类型 字段长度 字段顺序统一管理,避免不同开发人员各自建表导致结构不一致。
二、超级表基础结构
统一结构如下:
CREATE STABLE IF NOT EXISTS `<数据库名>`.`<超级表名>` ( `time` TIMESTAMP, `val` <数据类型>, `quality` INT ) TAGS ( ... );三个核心数据字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| time | TIMESTAMP | 数据采集时间 |
| val | 按业务定义 | 实际测点值 |
| quality | INT | 数据质量码 |
其中:
time、quality 固定 val 根据实际数据类型调整三、21 个标准 TAG 字段
业务手册已经明确规定超级表 TAG 字段名称及目标长度,例如device_name=300、variable_name=300、industrial_park=300、description=400等。
最终统一定义如下:
TAGS ( `device_name` NCHAR(300), `variable_name` NCHAR(300), `company` NCHAR(200), `region` NCHAR(200), `country` NCHAR(200), `province` NCHAR(200), `county` NCHAR(100), `industrial_park` NCHAR(300), `industry` NCHAR(100), `product_type` NCHAR(300), `system_code` VARCHAR(200), `operation` VARCHAR(100), `area_code` VARCHAR(100), `subsys_code` VARCHAR(200), `unit_code` VARCHAR(200), `system_path` VARCHAR(100), `point_code` VARCHAR(100), `description` VARCHAR(400), `unit` VARCHAR(100), `data_type` VARCHAR(100), `data_class` VARCHAR(100) );需要特别注意:
data_type使用下划线,不是:
data type四、统一超级表建表模板
开发人员实际使用时,只需要替换三个位置:
<数据库名> <超级表名> <数据类型>标准模板:
CREATE STABLE IF NOT EXISTS `<数据库名>`.`<超级表名>` ( `time` TIMESTAMP, `val` <数据类型>, `quality` INT ) TAGS ( `device_name` NCHAR(300), `variable_name` NCHAR(300), `company` NCHAR(200), `region` NCHAR(200), `country` NCHAR(200), `province` NCHAR(200), `county` NCHAR(100), `industrial_park` NCHAR(300), `industry` NCHAR(100), `product_type` NCHAR(300), `system_code` VARCHAR(200), `operation` VARCHAR(100), `area_code` VARCHAR(100), `subsys_code` VARCHAR(200), `unit_code` VARCHAR(200), `system_path` VARCHAR(100), `point_code` VARCHAR(100), `description` VARCHAR(400), `unit` VARCHAR(100), `data_type` VARCHAR(100), `data_class` VARCHAR(100) );五、DOUBLE 类型超级表示例
如果项目数值型数据统一采用DOUBLE,例如:
温度 压力 流量 电流 电压 频率 百分比可以建立:
CREATE STABLE IF NOT EXISTS `iot`.`sjcj_fd_double` ( `time` TIMESTAMP, `val` DOUBLE, `quality` INT ) TAGS ( `device_name` NCHAR(300), `variable_name` NCHAR(300), `company` NCHAR(200), `region` NCHAR(200), `country` NCHAR(200), `province` NCHAR(200), `county` NCHAR(100), `industrial_park` NCHAR(300), `industry` NCHAR(100), `product_type` NCHAR(300), `system_code` VARCHAR(200), `operation` VARCHAR(100), `area_code` VARCHAR(100), `subsys_code` VARCHAR(200), `unit_code` VARCHAR(200), `system_path` VARCHAR(100), `point_code` VARCHAR(100), `description` VARCHAR(400), `unit` VARCHAR(100), `data_type` VARCHAR(100), `data_class` VARCHAR(100) );对应关系:
超级表:sjcj_fd_double val:DOUBLE六、字符串类型超级表示例
如果业务侧将字符串类型统一抽象为:
strTDengine 建表时需要落到实际数据库字符串类型,例如项目约定使用:
VARCHAR(128)模板:
CREATE STABLE IF NOT EXISTS `iot`.`sjcj_fd_varchar128` ( `time` TIMESTAMP, `val` VARCHAR(128), `quality` INT ) TAGS ( `device_name` NCHAR(300), `variable_name` NCHAR(300), `company` NCHAR(200), `region` NCHAR(200), `country` NCHAR(200), `province` NCHAR(200), `county` NCHAR(100), `industrial_park` NCHAR(300), `industry` NCHAR(100), `product_type` NCHAR(300), `system_code` VARCHAR(200), `operation` VARCHAR(100), `area_code` VARCHAR(100), `subsys_code` VARCHAR(200), `unit_code` VARCHAR(200), `system_path` VARCHAR(100), `point_code` VARCHAR(100), `description` VARCHAR(400), `unit` VARCHAR(100), `data_type` VARCHAR(100), `data_class` VARCHAR(100) );项目内部如果把业务类型定义成:
double str需要注意:
double / str可以作为业务数据类型分类,但建表 SQL 中仍然需要使用 TDengine 实际支持的数据类型,例如DOUBLE、VARCHAR(128)等。
七、如果仍需要 FLOAT / INT
如果旧系统还有 FLOAT 或 INT 类型,也可以沿用完全相同的 TAG 模板。
FLOAT
CREATE STABLE IF NOT EXISTS `iot`.`sjcj_fd_float` ( `time` TIMESTAMP, `val` FLOAT, `quality` INT ) TAGS ( -- 21个标准TAG,保持不变 );INT
CREATE STABLE IF NOT EXISTS `iot`.`sjcj_fd_int` ( `time` TIMESTAMP, `val` INT, `quality` INT ) TAGS ( -- 21个标准TAG,保持不变 );因此实际设计原则不是“每种数据类型重新设计一套表”,而是:
同一套TAG + 不同val类型八、建表完成后的检查
查看超级表:
SHOW STABLES;检查字段定义:
DESCRIBE iot.sjcj_fd_double;查看完整建表 SQL:
SHOW CREATE STABLE iot.sjcj_fd_double;重点核对:
time val quality以及:
21个TAG字段名称 TAG类型 TAG长度 TAG顺序尤其确认:
data_type没有误写成其他名称。
九、开发使用规范
建议项目内部直接统一以下规则:
所有时序业务超级表统一使用
time + val + quality + 21个标准TAG。21 个 TAG 的字段名称、字段类型、字段长度和顺序统一管理,不允许开发自行调整。
不同数据类型只允许修改超级表名称和
val字段类型。当前项目如统一采用
double / str两类业务数据,应分别映射到数据库实际数据类型,例如DOUBLE和VARCHAR(128)。新建超级表后必须执行
DESCRIBE和SHOW CREATE STABLE进行结构核验。
十、总结
超级表统一后,数据模型就非常清晰:
超级表 │ ┌─────────────┼─────────────┐ │ │ │ time val quality TIMESTAMP 业务数据 INT │ ┌─────────┴─────────┐ DOUBLE VARCHAR │ ↓ 21 个统一 TAG这样做最大的价值是:
字段统一 结构统一 开发规范统一 数据接入统一 后期扩展简单 运维维护方便以后增加新的数据类型,也不需要重新设计 TAG,只需确定新的:
超级表名称 + val 数据类型即可。