3. 实体关系基础:关系(Relation)的定义、方向性、类型标签、关系表结构解析
在 ThingsBoard 中,实体(Entity)本身只是数据容器,真正让物联网数据链路“流动”起来的,是实体之间的关系(Relation)。关系定义了资产、设备、仪表板、规则链等实体之间的连接方式,是构建数字孪生与资产拓扑的核心要素。
3.1 关系的定义与核心要素
一个关系本质上是一条有向边,连接两个实体,并携带语义标签。每个关系由以下四个核心要素唯一确定:
| 要素 | 说明 | 示例值 |
|---|---|---|
| 从实体(From) | 关系的起始节点,可以是任何实体类型 | 资产 ID: 9a3f7b2e-... (Asset) |
| 到实体(To) | 关系的目标节点,可以是任何实体类型 | 设备 ID: 1c8d4f6a-... (Device) |
| 类型(Type) | 关系的语义标签,区分不同业务含义 | "Contains"、"Manages"、"Routes" |
| 方向性(Direction) | 关系是单向还是双向查询 | FROM → TO |
关键认知: ThingsBoard 的关系是有向的,但查询时支持反向遍历。例如,从资产查询“包含哪些设备”是正向,从设备查询“属于哪个资产”是反向。这种设计既保留了方向语义,又提供了灵活的图遍历能力。
3.2 方向性:单向存储,双向查询
关系在数据库中只存储一次,方向由 from_id 和 to_id 字段决定。但在 API 和规则链中,你可以通过 direction 参数指定查询方向:
- FROM → TO(正向):查找从当前实体出发的所有关系。
- TO → FROM(反向):查找指向当前实体的所有关系。
- BOTH(双向):同时查找正向和反向关系。
这种设计使得资产-设备层级、规则链连接、仪表板关联等场景都能高效建模,而无需为反向关系额外存储数据。
实践建议: 在建模时,始终从“业务语义”出发定义方向。例如,“资产包含设备”比“设备属于资产”更符合物理世界的直觉,因此将资产设为 From,设备设为 To,类型设为 "Contains"。
3.3 类型标签:语义化的连接符
类型标签(Type)是一个字符串,用于区分不同业务含义的关系。ThingsBoard 预定义了一些常用类型,同时也支持用户自定义。以下是常见的关系类型及其应用场景:
| 关系类型 | 典型场景 | From → To 示例 |
|---|---|---|
Contains |
资产包含子资产或设备 | 工厂资产 → 生产线资产 |
Manages |
资产管理设备 | 网关资产 → 传感器设备 |
Routes |
规则链节点之间的数据流 | 筛选节点 → 转换节点 |
Belongs_To |
设备归属资产(反向语义) | 设备 → 资产 |
Uses |
仪表板引用资产或设备 | 仪表板 → 资产 |
注意: 类型标签是大小写敏感的。建议使用驼峰命名法(如
Contains、Manages),并在团队内保持命名规范一致,避免因拼写差异导致查询失败。
3.4 关系表结构解析
ThingsBoard 使用关系型数据库(PostgreSQL 或 Cassandra)存储关系数据。以下是关系表的核心结构(以 PostgreSQL 为例):
-- 关系表核心字段(简化版)
CREATE TABLE relation (
from_id UUID NOT NULL, -- 起始实体 ID
from_type VARCHAR(32) NOT NULL, -- 起始实体类型(如 ASSET、DEVICE)
to_id UUID NOT NULL, -- 目标实体 ID
to_type VARCHAR(32) NOT NULL, -- 目标实体类型
relation_type VARCHAR(64) NOT NULL, -- 关系类型标签
additional_info JSONB, -- 附加信息(可选)
PRIMARY KEY (from_id, from_type, relation_type, to_id, to_type)
);
-- 常用索引:支持反向查询
CREATE INDEX idx_relation_to_id ON relation(to_id, to_type, relation_type);
表结构的关键设计点:
- 复合主键:确保同一起始实体到同一目标实体之间,同一类型的关系只能存在一条。
- 实体类型字段:
from_type和to_type记录了实体类型,使得关系可以跨不同类型实体建立。 - 附加信息:
additional_info字段为 JSONB 类型,可用于存储关系的元数据,如权重、时间戳、描述等。 - 反向索引:
idx_relation_to_id索引加速了反向查询(从目标实体查找来源实体)。
3.5 关系数据链路可视化
下图展示了一个典型的资产-设备关系链路,以及关系在其中的作用:
3.6 关系操作与最佳实践
在 ThingsBoard 中,关系可以通过 REST API、规则链节点或 UI 界面进行管理。以下是常用的关系操作:
| 操作 | API 端点(示例) | 说明 |
|---|---|---|
| 创建关系 | POST /api/relation |
指定 from、to、type 创建关系 |
| 删除关系 | DELETE /api/relation |
根据主键删除指定关系 |
| 查询正向关系 | GET /api/relations?fromId=...&fromType=ASSET |
查找从指定实体出发的所有关系 |
| 查询反向关系 | GET /api/relations?toId=...&toType=DEVICE |
查找指向指定实体的所有关系 |
| 递归查询 | GET /api/relations?fromId=...&fromType=ASSET&level=3 |
查找指定层级内的所有关联实体 |
建模最佳实践:
- 保持关系类型简洁:一个业务场景使用一个关系类型,避免语义重叠。例如,不要同时使用 "Contains" 和 "Has" 表示包含关系。
- 利用附加信息:当关系需要携带额外属性(如连接时间、配置参数)时,使用
additional_info字段,而不是创建多个关系。 - 避免循环关系:在资产层级中,避免 A → B → A 的循环关系,这会导致递归查询陷入死循环。
- 批量操作注意性能:当需要创建大量关系(如批量导入设备)时,建议使用批量 API 或事务性操作,减少数据库连接开销。
3.7 关系与实体数据链路的协同
关系是实体数据链路的“粘合剂”。通过关系,ThingsBoard 实现了以下关键能力:
- 资产拓扑遍历:从顶层资产出发,递归查询所有子资产和设备,构建完整的数字孪生结构。
- 规则链数据路由:规则链节点之间的关系定义了消息的流转路径,实现数据过滤、转换和持久化。
- 仪表板数据绑定:仪表板通过关系关联资产和设备,实现动态数据展示。
- 告警传播:设备告警可以通过关系向上传播到关联资产,实现层级告警管理。