无模式写入
在物联网应用中,为了实现自动化管理、业务分析和设备监控等多种功能,通常需要采集大量的数据项。然而,由于应用逻辑的版本升级和设备自身的硬件调整等原因,数据采集项可能会频繁发生变化。为了应对这种挑战,TDengine 提供了无模式(schemaless)写入方式,旨在简化数据记录过程。
采用无模式写入方式,用户无须预先创建超级表或子表,因为 TDengine 会根据实际写入的数据自动创建相应的存储结构。此外,在必要时,无模式写入方式还能自动添加必要的数据列或标签列,确保用户写入的数据能够被正确存储。
值得注意的是,通过无模式写入方式创建的超级表及其对应的子表与通过 SQL 直接创建的超级表和子表在功能上没有区别,用户仍然可以使用 SQL 直接向其中写入数据。然而,由于无模式写入方式生成的表名是基于标签值按照固定的映射规则生成的,因此这些表名可能缺乏可读性,不易于理解。
采用无模式写入方式时会自动创建表,无须手动创建表。手动建表的话可能会出现未知的错误。
无模式写入行协议
TDengine 的无模式写入行协议兼容 InfluxDB 的行协议、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。InfluxDB、OpenTSDB 的标准写入协议请参考各自的官方文档 。
下面首先以 InfluxDB 的行协议为基础,介绍 TDengine 扩展的协议内容。该协议允许用户采用更加精细的方式控制(超级表)模式。采用一个字符串来表达一个数据行,可以向写入 API 中一次传入多行字符串来实现多个数据行的批量写入,其格式约定如下。
measurement,tag_set field_set timestamp
各参数说明如下。
- measurement 为数据表名,与 tag_set 之间使用一个英文逗号来分隔。
- tag_set 格式形如
<tag_key>=<tag_value>, <tag_key>=<tag_value>
,表示标签列数据,使用英文逗号分隔,与 field_set 之间使用一个半角空格分隔。 - field_set 格式形如
<field_key>=<field_value>, <field_key>=<field_value>
,表示普通列,同样使用英文逗号来分隔,与 timestamp 之间使用一个半角空格分隔。 - timestamp 为本行数据对应的主键时间戳。
- 无模式写入不支持含第二主键列的表的数据写入。
tag_set 中的所有的数据自动转化为 nchar 数据类型,并不需要使用双引号。 在无模式写入数据行协议中,field_set 中的每个数据项都需要对自身的数据类型进行描述,具体要求如下。
- 如果两边有英文双引号,表示 varchar 类型,例如 "abc"。
- 如果两边有英文双引号而且带有 L 或 l 前缀,表示 nchar 类型,例如 L" 报错信息 "。
- 如果两边有英文双引号而且带有 G 或 g 前缀, 表 示 geometry 类型, 例 如G"Point(4.343 89.342)"。
- 如果两边有英文双引号而且带有 B 或 b 前缀,表示 varbinary 类型,双引号内可以为 \x 开头的十六进制或者字符串,例如 B"\x98f46e" 和 B"hello"。
- 对于空格、等号(=)、逗号(,)、双引号(")、反斜杠(\),前面需要使用反斜杠(\)进行转义(均为英文半角符号)。无模式写入协议的域转义规则如下表所示。
序号 | 域 | 需转义字符 |
---|---|---|
1 | 超级表名 | 逗号,空格 |
2 | 标签名 | 逗号,等号,空格 |
3 | 标签值 | 逗号,等号,空格 |
4 | 列名 | 逗号,等号,空格 |
5 | 列值 | 双引号,反斜杠 |
如果使用两个连续的反斜杠,则第1个反斜杠作为转义符,当只有一个反斜杠时则无须转义。无模式写入协议的反斜杠转义规则如下表所示。
序号 | 反斜杠 | 转义为 |
---|---|---|
1 | \ | \ |
2 | \\ | \ |
3 | \\\ | \\ |
4 | \\\\ | \\ |
5 | \\\\\ | \\\ |
6 | \\\\\\ | \\\ |
数值类型将通过后缀来区分数据类型。无模式写入协议的数值类型转义规则如下表所示。
序号 | 后缀 | 映射类型 | 大小(字节) |
---|---|---|---|
1 | 无或 f64 | double | 8 |
2 | f32 | float | 4 |
3 | i8/u8 | TinyInt/UTinyInt | 1 |
4 | i16/u16 | SmallInt/USmallInt | 2 |
5 | i32/u32 | Int/UInt | 4 |
6 | i64/i/u64/u | BigInt/BigInt/UBigInt/UBigInt | 8 |
- t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。
例如如下数据行表示:向名为 st 的超级表下的 t1 标签为 "3"(NCHAR)、t2 标签为 "4"(NCHAR)、t3 标签为 "t3"(NCHAR)的数据子表,写入 c1 列为 3(BIGINT)、c2 列为 false(BOOL)、c3 列为 "passit"(BINARY)、c4 列为 4(DOUBLE)、主键时间戳为 1626006833639000000 的一行数据。
st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000
需要注意的是,如果描述数据类型后缀时出现大小写错误,或者为数据指定的数据类型有误,均可能引发报错提示而导致数据写入失败。
TDengine 提供数据写入的幂等性保证,即您可以反复调用 API 进行出错数据的写入操作。但是不提供多行数据写入的原子性保证。即在多行数据一批次写入过程中,会出现部分数据写入成功,部分数据写入失败的情况。
无模式写入处理规则
无模式写入按照如下原则来处理行数据:
-
将使用如下规则来生成子表名:首先将 measurement 的名称和标签的 key 和 value 组合成为如下的字符串
"measurement,tag_key1=tag_value1,tag_key2=tag_value2"