本文面向读者:
正在使用 TDengine TSDB 或对 TDengine TSDB 有一定了解,希望在业务中应用或尝试学习使用 TDengine IDMP 的技术人员
引言
相比于 TSDB,IDMP 的使用门槛更低。但是在真正开始使用 IDMP 各项功能之前,需要先完成资产数据导入。由于资产导入过程涉及的新概念较多,对刚刚接触 IDMP 的人来说,这个过程会比较困难。
本文的目标是用尽可能通俗易懂的语言,尽可能简明的举例与演示,从简单到复杂,从单个到批量,从标准场景到自定义场景,逐步讲清楚 IDMP 资产数据的导入方法。
什么是资产数据导入?
首先需要理解三个重要概念。
- 树状结构:

- 元素:
- 树状结构里的每个节点被称之为元素 (Element)。如图所示,元素可以是具体的物理设备,也可以是逻辑的,比如一座工厂、一个集团等。
- 属性:
- 每个元素都有自己的属性,例如 “风机-1” 元素,就可能有安装地址、设备 ID、电机转速等属性,一般来说,一个元素的一个属性会与 TSDB 中一张子表的一个字段(数据列或 Tag 列)存在引用关系。
理解了上述三个概念,就可以理解资产数据导入:
所谓资产数据导入,就是在 IDMP 中,根据业务场景创建树状结构,并把各个元素的属性与 TSDB 中对应子表的对应字段一一建立引用关系。

如上图所示,配置好这种引用关系,IDMP 中以树状结构管理的资产数据才能汲取到 TSDB 中的数据源泉,这棵树才能 “活”起来。
注意:为了直观展示,只展示了最后一层元素的属性,实际上每一层元素都可以有自己的属性、面板等配置选项;
为了直观展示,只描述了属性与子表列恰好一一对应的情况,实际上树状结构中元素的组织方式可以任意设置,一个元素的属性可能来自多个超级表或子表
资产数据导入会遇到哪些问题?
如果在 TSDB 数据建模之初,就已经充分考虑了数据目录问题,建模很理想,那么资产数据就可以通过简单的配置自动批量导入(见 5.9)。
但是,大多数业务应用场景下:
- 在进行 TSDB 数据建模的时候,可能完全没有考虑过将来会需要以树状结构来进行资产管理
- 由于业务数据的特点以及管理需求,TSDB 中的建模方式无法按照理想情况进行设计实施
- IDMP 中可能需要以多种树状结构进行资产管理,TSDB 的数据模型不可能同时匹配所有树状结构
因此,IDMP 实际应用场景中,资产数据自动导入功能很难用得上,用户会发现自己经常要进行大量手动配置,资产数据导入操作对于刚刚接触 IDMP 的人来说就会变得比较困难。
不过不必担心,因为
凡是需要手动重复的操作,IDMP 里都提供了批量处理的方法!
准备说明就到这里,接下来,请您跟随本文的思路,由简单到复杂,由逐个手动配置到批量自动配置,一步步深入了解 IDMP 的资产数据导入吧!
准备工作
我们准备三个场景,用于介绍与演示各种应用场景下,资产数据导入的各种方法:
- TSDB 数据建模非常适合 IDMP 资产数据导入的场景:智能电表标准场景
- TSDB 中使用单列模型,tag 关联信息比较完善的场景:智能电表单列模型场景
- TSDB 中使用单列模型,而且关联信息缺失场景:无关联单列模型场景
安装部署
安装部署 TSDB 与 IDMP ,可参考 https://idmpdocs.taosdata.com/get-started/get-started-docker
智能电表标准场景准备
在 TSDB 服务端运行
taosBenchmark -n 100 -t 100
100 个智能电表设备数据就准备好了。
超级表表结构如下:

值得说明的是,标签字段 location,已经按照地址进行了设计,用 “.” 分隔的字符串内容可以直接用于 IDMP 的树状结构路径中。(标签中选择 location 即可获得下图所示的层级展示效果)

如果我们恰好希望用路径信息在 IDMP 中创建树状结构,每个最小的元素恰好对应一个智能电表设备,那么上述建模方式就可以认为是一种 “理想建模” 方式。
智能电表单列模型场景准备
假设智能电表场景中,用单列模型,三张超级表分别存储电流、电压、相位数据
- 三个超级表:
current_meters:存储电流数据voltage_meters:存储电压数据phase_meters:存储相位数据
- 单列模型:每个超级表只有两个字段
ts:时间戳(主键)xxx_value:对应的测量值
- 标签设计:
- 只有一个tag:
device_id - 相同设备的三个子表使用相同的
device_id
- 只有一个tag:
- 子表数量:
- 每个超级表10张子表
- 总共30张子表(10个设备 × 3种测量类型)
建表语句如下
-- 创建电流超级表
CREATE STABLE meters_current (
ts TIMESTAMP,
current_value FLOAT
) TAGS (device_id NCHAR(20));
-- 创建电压超级表
CREATE STABLE meters_voltage (
ts TIMESTAMP,
voltage_value FLOAT
) TAGS (device_id NCHAR(20));
-- 创建相位超级表
CREATE STABLE meters_phase (
ts TIMESTAMP,
phase_value FLOAT
) TAGS (device_id NCHAR(20));
-- 为10个设备创建电流子表
CREATE TABLE current_meter_1 USING meters_current TAGS ('device_001');
CREATE TABLE current_meter_2 USING meters_current TAGS ('device_002');
CREATE TABLE current_meter_3 USING meters_current TAGS ('device_003');
CREATE TABLE current_meter_4 USING meters_current TAGS ('device_004');
CREATE TABLE current_meter_5 USING meters_current TAGS ('device_005');
CREATE TABLE current_meter_6 USING meters_current TAGS ('device_006');
CREATE TABLE current_meter_7 USING meters_current TAGS ('device_007');
CREATE TABLE current_meter_8 USING meters_current TAGS ('device_008');
CREATE TABLE current_meter_9 USING meters_current TAGS ('device_009');
CREATE TABLE current_meter_10 USING meters_current TAGS ('device_010');
-- 为10个设备创建电压子表
CREATE TABLE voltage_meter_1 USING meters_voltage TAGS ('device_001');
CREATE TABLE voltage_meter_2 USING meters_voltage TAGS ('device_002');
CREATE TABLE voltage_meter_3 USING meters_voltage TAGS ('device_003');
CREATE TABLE voltage_meter_4 USING meters_voltage TAGS ('device_004');
CREATE TABLE voltage_meter_5 USING meters_voltage TAGS ('device_005');
CREATE TABLE voltage_meter_6 USING meters_voltage TAGS ('device_006');
CREATE TABLE voltage_meter_7 USING meters_voltage TAGS ('device_007');
CREATE TABLE voltage_meter_8 USING meters_voltage TAGS ('device_008');
CREATE TABLE voltage_meter_9 USING meters_voltage TAGS ('device_009');
CREATE TABLE voltage_meter_10 USING meters_voltage TAGS ('device_010');
-- 为10个设备创建相位子表
CREATE TABLE phase_meter_1 USING meters_phase TAGS ('device_001');
CREATE TABLE phase_meter_2 USING meters_phase TAGS ('device_002');
CREATE TABLE phase_meter_3 USING meters_phase TAGS ('device_003');
CREATE TABLE phase_meter_4 USING meters_phase TAGS ('device_004');
CREATE TABLE phase_meter_5 USING meters_phase TAGS ('device_005');
CREATE TABLE phase_meter_6 USING meters_phase TAGS ('device_006');
CREATE TABLE phase_meter_7 USING meters_phase TAGS ('device_007');
CREATE TABLE phase_meter_8 USING meters_phase TAGS ('device_008');
CREATE TABLE phase_meter_9 USING meters_phase TAGS ('device_009');
CREATE TABLE phase_meter_10 USING meters_phase TAGS ('device_010');
本文主要介绍资产数据导入,因此只需要建表后有元数据即可,是否有时序数据并不重要。
无关联单列模型场景准备
单列模型,一个超级表,100 张子表,tag 上没有有效的关联信息,模拟一种最不适合 IDMP 批量导入资产数据的场景。
使用 taosBenchmark 即可生成
taosBenchmark -A "int" -l 1 -b float -t 100 -n 100 -d single
表结构如下:

IDMP 资产数据导入之旅
让我们开始。
基础操作:
- 创建一个带有层级的智能电表元素
- 给这个元素创建一个属性并与一个子表数据列建立关联
- 给这个元素创建多个属性与一个子表的多个列建立关联
- 使用元素模板,批量配置属性
- 使用资产模型,批量创建元素并导入资产数据
进阶操作:
- 智能电表场景还是过于理想,如果一个元素的属性来自多个超级表呢?不慌,可以建多个资产模型
- 配置元素模板和资产模型太多了,不慌,有数据导入功能
- 元素属性配置无法通过资产模型实现怎么办?不慌,数据导入功能可以指定子表
- 最后,我们回头看下最理想的数据简单导入场景
如果您能跟随本文的思路,走完上述流程,相信您对 IDMP 的资产数据导入能够有更加清晰、全面的认知。
创建带有层级的智能电表元素
第一步,我们就按照智能电表的 location ,创建一个如图所示的元素(严格来讲不是 1 个是 4 个)

我们的目的是让这个名为 d13 的元素与 TSDB 中的 d13 子表建立关联

创建的步骤,就是层层新建子元素,不用选择模板(这里留意下,后面会用到),然后在 “通用” 选项中编辑各级元素的名称
新建子元素操作步骤



给这个元素创建一个属性并与一个子表数据列建立关联
我们希望 IDMP中 d13 元素与 TSDB 中 d13 子表建立关联。
子表有多个数据列与 tag 列,而现在的 d13 元素没有任何属性与这些列对应。

点击新属性,我们创建一个名为“电流”的属性,与子表 d13 的数据列 “current” 建立引用关系
current 在子表中是一个数据列,因此引用类型需要选 TDengine 指标

数据引用设置,直接选择即可

保存后就能看到元素 d13 多了一个名为“电流”的属性,而且该属性的引用设置已经配置完成,数据引用自 test 库下, d13 表, current 数据列。

这样就完成了一个元素属性与一个子表字段的关联,或者说引用关系的建立。
给这个元素创建多个属性与一个子表的多个列建立关联
点击下图加号按钮,新增下一个属性并配置引用设置

重复 5.2 操作,可以创建多个属性并与表建立引用关系(注意不同的属性名称、数据类型、引用类型)

理论上讲,我们可以通过重复 5.1 -5.3 的操作,手动在 IDMP 中创建的所有元素并逐个进行属性配置,来完成资产数据导入。
显然,当我们有大量元素需要进行属性引用关系配置时,手动操作过于繁琐,因此我们进入下一节。
使用元素模板,批量配置属性
我们现在树状结构的设计是按设备创建最后一层元素,每个设备元素的属性结构实际上是相同的,那么还记得我们前文提过的:
凡是需要手动重复的操作,IDMP 里都提供了批量处理的方法!
既然最后一层元素的属性结构完全相同,那么这个元素就可以用 “元素模板” 来创建,有了模板,就不用逐个添加属性引用了。
模板需要在 “基础库” 中创建


这里会遇到一个难点,元素命名模式中那个可替换字符串 ${KEYWPRD1}
初次遇到这个东西的 IDMP 用户通常会一头雾水,因为所有提供更多灵活性的设计注定会导致操作变得更加复杂,理解门槛更高。
实际上这个功能很好理解:
我们的目的是创建一个模板,以后创建智能电表元素就不用逐个配置属性了。
当我使用这个模板创建一个新元素的时候,遇到的第一个问题就是:元素名叫什么?
我的模板叫 “标准智能电表” ,但我的元素不叫这个名字,我们在 5.1 创建的元素,元素名称和它对应的子表名称相同,叫做 “d13”
因此,IDMP 模板创建时才有 “元素命名模式” 这个设计,可以添加一个或多个可替换字符串 ,当我们用模板创建新元素时,会需要用户填写可替换字符串的具体内容,给元素进行命名

我们当前的目标,就是希望元素名称和子表名称一致即可,因此,我们需要的可替换字符串,只有一个 ${KEYWPRD1},它就是子表名称,为了在创建元素时提醒我们应该填写什么内容,需要在描述中添加上提示词

为了表示区分,我们把用元素模板创建的元素,名称前面加一个 “dev_”,需要按下图所示配置

保存这个模板,接下来为这个元素模板添加属性模板

和手动添加属性基本一样,需要注意数据引用表达式中,源表名称模式的设置

接下来给元素模板配置它的属性模板。
属性模板中的源表名称模式,与元素模板的元素命名模式类似,这是一个属性模板,我们需要用模板与各个子表的字段建立引用关系,因此模板的源表肯定不能是写死的,那么源表是谁呢?显然,在现在的场景下,我们希望创建的元素与哪个子表关联,这个属性的源表就是谁,而刚刚我们已经把 ${KEYWPRD1} 定义为了子表名称,因此在这里直接填写 ${KEYWPRD1} 就好。(这是一个简单的场景,因此只有一个可替换字符串,实际上可替换字符串功能很强大,可以设置多个,实现更灵活的配置)
配置好所有属性模板如下图所示:
( location 信息已经在树状结构中就不配置了)

接下来我们用这个模板创建一个新的元素
查阅 tsdb ,d17 子表也在当前 California-Campbell 路径下,用元素模板 “标准智能电表” 创建一个元素
还记得 5.1 中,我们提到创建元素不需要选择模板吗?现在需要了。
在 Campbell 下创建新的子元素,使用刚刚创建的模板,此时会需要我们填写可替换字符串,提示词已经出现,我们输入 d17

点击确认,一个符合我们命名要求,具备所有属性的元素 dev_d17 就直接被创建出来了。

上述操作就可以避免为每个元素配置一遍属性。理论上我们可以用模板逐个创建元素,就能把全部 100 个设备的资产数据导入。
但重复操作 100 次过于繁琐,IDMP 提供了批量的操作方法。
使用资产模型,批量创建元素并导入资产数据
IDMP 的使用过程中,要随时牢记:
凡是需要手动重复的操作,IDMP 里都提供了批量处理的方法!
我们现在已经有了元素模板、属性模板,用来对配置属性的动作进行批量操作,那么有没有一个功能,能够对“使用模板创建元素”这个动作进行批量操作呢?有的!这个功能就是资产模型。
所谓资产模型,可以理解为用元素模板创建元素的一种批量操作配置。从管理后台-连接-TDengine 进入资产模型配置页面


资产模型配置过程中,需要注意元素名称和元素路径两个配置项。
元素名称这里我们已经解释过,批量导入的时候,元素名称肯定不能固定,需要与子表名称一致。
点击 + 按钮,可以选择元素名称需要涉及的表字段(tag 列与子表名)

您可能要问,刚才的替换字符串 ${KEYWPRD1} 呢?注意,资产模型配置中,不涉及可替换字符串。
可配置字符串只在手动使用元素模板创建元素时有作用,所以这里用不到。我们直接用 tbname 这个 TSDB 中的伪列来引用子表名称。
(伪列概念介绍: https://docs.taosdata.com/reference/taos-sql/select/#%E4%BC%AA%E5%88%97)
为了与刚才手动创建的元素区分,我们在元素名称前面加上 “asset_” 前缀。
元素路径,就是元素在树状结构的位置,用带 “.” 的分隔符表示,例如我们 5.1 创建的元素 d13 ,它的路径就是 “ 智能电表标准场景.California.Campbell”。如果路径不存在,IDMP 会自动创建。
在智能电表标准场景中,建模很理想,标签字段 location 已经按照地址进行了设计,因此可以直接引用作为路径。
配置完成后如下图所示:

元素模板和设备属性已经配置好,可以看到已经自动完成了映射。如果遇到特殊情况,可以手动修改模板中的属性与子表中字段的对应关系。

点击完成,IDMP 会开始自动进行资产数据导入动作,等待完成即可。

回到元素浏览器,会看到所有元素都被自动创建,命名与路径符合我们的预期,一次资产数据批量导入就此完成!

回顾本节内容,通过创建资产模型,似乎很容易就能批量导入资产数据。但是请注意,5.1-5.5 的所有操作,都是建立在元素与子表一一对应,数据建模与元素建模完全匹配的前提下!
而用户实际使用 IDMP 过程中,大概率不会这么理想。接下来我们看,数据建模并不理想的情况下,该如何实现批量导入。
智能电表场景还是过于理想,如果一个元素的属性来自多个超级表呢?不慌,可以建多个资产模型
很多时候用户现场只能建单列模型。我们假设这么一个场景:同样是智能电表的设备数据,但是电流、电压、相位分别创建了一张超级表,每个超级表只有一个数据列。三个超级表有相同的标签列 device_id ,来自同一个设备的标签值相同。详见 4.3。
我们在 IDMP 的树形结构中,依然希望最底层每个元素是一个设备,便于将来分析使用。那么此时,一个元素的属性就来自三个不同的子表。
手动创建元素属性时,问题不大,因为属性与子表列引用关系是单独配置的,注意选择就行。

按照 5.4 的流程,我们尝试创建这个元素的元素模板。
创建元素模板 “单列智能电表” ,我们使用 device_id 这个 tag 的内容作为元素名称

在本场景下,创建属性模板时,问题出现了,源表名称和 device_id 并不相同,device_id 形如:“ device_001” ,子表名是 “current_meter_1”,我们不能用元素命名模式中的可替换字符串来代替属性模板的命名规则了。
此时我们可以引入第二个可替换字符串,用于属性模板,替换子表名称最后的设备编号值,如图所示:

(当然不嫌麻烦的话用 ${KEYWORD2} 替换完整的子表名称也可以)
使用子表名称最后一位编号值作为可替换字符串,好处在于配置其它属性模板时,这个 ${KEYWORD2} 可以复用

通过这个模板创建元素

接下来才是真正的问题:这样的应用场景,如何使用资产模型批量导入呢?
要注意到,一个资产模型只能配置一个超级表的字段引用关系,因此,当需要配置 3 个超级表的资产导入时,我们需要配置 3 次资产模型。
例如电流属性的批量导入,需要按下图所示:

配置完成,导入数据后,结果如下,可以看到只有电流有完整的引用关系,另外两个属性引用不完整

再对电压、相位进行资产模型创建与导入(注意元素名称有前缀 “asset_” ,三次导入,元素名称配置必须保持相同)
配置完成后,效果如下

在管理后台可以看到此时已经创建的资产模型

这其实是一个很有代表性的场景,一个元素的属性可以来自多个库、多个超级表。例如元素有 5 个属性,2 个来自超级表 st1 ,3 个来自超级表 st2,也可以按上述方法进行配置。
配置元素模板和资产模型太多了,不慌,有数据导入功能
真实应用场景中,用户很可能会创建多种树状结构,需要创建大量的元素模板,为了实现资产数据导入需要创建大量的资产模型,用 5.4 – 5.6 的方法还是需要太多手动操作。
当我们需要一次性导入大量的模板以及资产模型时,可以使用 IDMP 数据导入功能。

数据导入,实际上就是将大量的元素模板与资产模型配置按规定格式写到一个 csv 文件中,然后让 IDMP 导入这个文件,就会批量创建模板并导入资产数据了。
那么这个 csv 表格怎么编写呢?
简单来说,元素模板与资产模型怎么创建的,这个表就怎么写。
首先需要下载一个模板文件,在这个基础上进行修改。

之前的操作都在 test 这个数据库里,因此我们就选择 test

(注意导入导出的表格必须是 utf-8 格式)
实际上我们只需要这个表头就足够。
这个表格乍一看十分复杂,字段很多,但是如果您已经跟随本文从 5.1 走到 5.6,见证了 4 个资产模型的配置过程,那么表中的各个字段就很容易理解了。
配置资产模型时,需要指定数据库、超级表、元素模板、元素名称、元素路径,以及表字段与元素属性的对应关系,数据导入表需要填写的也就是这些内容。而且,使用数据导入功能不需要提前创建元素模板,IDMP 会根据 csv 文件的内容自动创建。
我们把之前创建的 4 个资产模型全部放到 csv 中,去掉无效内容,如下表所示:

可以看到,4 个资产模型以及涉及到的元素模板的主要配置信息都在表中,因此使用数据导入功能,导入该 csv 文件,即可一次性创建和导入 5.1-5.6 的所有资产数据。

好了,到这里,我们已经掌握了如何批量创建元素模板与资产模型的方法。
但是,还有一种情况需要考虑,那就是由于建模的缺陷,无法配置资产模型来进行批量导入。
元素属性配置无法通过资产模型实现怎么办?不慌,数据导入功能可以指定子表
在创建资产模型的时候我们注意到,当元素的属性来自多个超级表时,需要各个超级表都有至少一个相关联的字段,能够让我们把不同超级表的字段引用关系配置到同一个路径下的同一个元素中。
例如在 5.6 中,我们依赖三个超级表都有的标签列 device_id ,才能把三个超级表的数据导入到同一个元素下,如果没有这个标签列,我们就无法在资产模型中配置元素名称。

那么问题来了,如果数据建模的时候没有考虑到这个问题,不存在可以用来作为元素名称的标签列,还能否进行批量操作呢?
完全可以的,同样还是使用数据导入功能。
5.7 中,我们只展示了使用 csv 文件配置资产导入的过程,这个过程不需要配置子表名称。如果我们有特别的需求,需要指定子表列的引用关系,同样可以用 csv 文件来实现。
如果指定子表名称,表中的一行内容,实际上就是描述了一个元素属性与一个子表字段的引用关系,可以描述任意场景的资产数据导入过程。
我们使用 4.4 的无关联单列模型场景举例
单列模型,一个超级表,100 张子表,tag 上没有有效的关联信息(详见 4.4)。
假设我们需要创建的元素,有 3 个属性,三个元素的属性分别来自编号 0-2,3-5,6-8 的子表的数据列。
不需要在 IDMP 中做任何编辑,只需要在模板 csv 文件中填写如下内容,即可实现。

点击导入,选择编辑好的文件,开始导入

IDMP 会自动创建元素模板,并根据文件建立数据引用关系,效果如下图所示

可见,使用数据导入功能,可以用 csv 文件批量导入任意树状结构。
最后,我们回头看下最理想的数据简单导入场景
在 4.1 的场景下,因为建模非常理想,不需要设计树状结构,不需要创建元素模板,不需要创建资产模型,默认使用子表名作为最后元素名称,使用简单导入功能可以一键导入 test 库 meters 超级表所有资产数据。

总结
如果您能跟随本文的思路,一路走到这里,恭喜您,已经对 IDMP 资产导入功能有了比较全面的了解。
其它诸如可替换字符串的更多用法,更多数据引用类型的应用场景,属性单位的自动转换等高级用法,在后续对 IDMP 的深入使用过程中可以进一步了解。
本文旨在用尽可能通俗易懂的语言,尽可能简明的举例与演示,逐步讲清楚 IDMP 资产数据的导入方法。更多详细内容请参考官网文档 https://idmpdocs.taosdata.com/ 。



























