数据类型
在 TDengine 中,普通表的数据模型中可使用以下数据类型。
| # | 类型 | Bytes | 说明 |
|---|---|---|---|
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒和纳秒。 |
| 2 | INT | 4 | 整型,范围 [-2^31, 2^31-1] |
| 3 | INT UNSIGNED | 4 | 无符号整数,[0, 2^32-1] |
| 4 | BIGINT | 8 | 长整型,范围 [-2^63, 2^63-1] |
| 5 | BIGINT UNSIGNED | 8 | 无符号长整型,范围 [0, 2^64-1] |
| 6 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
| 7 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] |
| 8 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 NCHAR |
| 9 | SMALLINT | 2 | 短整型,范围 [-32768, 32767] |
| 10 | SMALLINT UNSIGNED | 2 | 无符号短整型,范围 [0, 65535] |
| 11 | TINYINT | 1 | 单字节整型,范围 [-128, 127] |
| 12 | TINYINT UNSIGNED | 1 | 无符号单字节整型,范围 [0, 255] |
| 13 | BOOL | 1 | 布尔型 |
| 14 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 NCHAR 字符占用 4 字节的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 \'。NCHAR 使用时须指定字符串大小,类型为 NCHAR(10) 的列表示此列的字符串最多存储 10 个 NCHAR 字符。如果用户字符串长度超出声明长度,将会报错。 |
| 15 | JSON | JSON 数据类型,只有 Tag 可以是 JSON 格式 | |
| 16 | VARCHAR | 自定义 | BINARY 类型的别名 |
| 17 | GEOMETRY | 自定义 | 几何类型 |
| 18 | VARBINARY | 自定义 | 可变长的二进制数据 |
| 19 | DECIMAL | 8 或 16 | 高精度数值类型,取值范围取决于类型中指定的 Precision 和 Scale |
| 20 | BLOB | 最大长度 4MB | 可变长的二进制数据 |
-
表的每行长度不能超过 64KB(注意:每个 BINARY/NCHAR/GEOMETRY/VARBINARY 类型的列还会额外占用 2 个字节的存储位置)。
-
虽然 BINARY 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 BINARY 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 NCHAR 类型进行保存。如果强行使用 BINARY 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏等情况。
-
BINARY 类型理论上最长可以有 65,517(标签列为 16,382)字节。BINARY 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 BINARY(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 字节的存储空间,总共固定占用 20 字节的空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即
\'。 -
GEOMETRY 类型数据列为最大长度为 65,517 字节,标签列最大长度为 16,382 字节。支持 2D 的 POINT、LINESTRING 和 POLYGON 子类型数据。长度计算方式如下表所示:
# 语法 最小长度 最大长度 每组坐标长度增长 1 POINT(1.0 1.0) 21 21 无 2 LINESTRING(1.0 1.0, 2.0 2.0) 9+2*16 9+4094*16 +16 3 POLYGON((1.0 1.0, 2.0 2.0, 1.0 1.0)) 13+3*16 13+4094*16 +16 -
SQL 语句中的数值类型将依据是否存在小数点,或使用科学计数法表示,来判断数值类型是否为整型或者浮点型,因此在使用时要注意相应类型越界的情况。例如,9999999999999999999 会认为超过长整型的上边界而溢出,而 9999999999999999999.0 会被认为是有效的浮点数。
-
VARBINARY 是一种存储二进制数据的数据类型,最大长度为 65,517 字节,标签列最大长度为 16,382 字节。可以通过 sql 或 schemaless 方式写入二进制数据(需要转换为
\x开头的字符串写入),也可以通过 stmt 方式写入(可以直接使用二进制)。显示时通过 16 进制\x开头。
时间戳
使用 TDengine TSDB,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则:
- 时间格式为
YYYY-MM-DD HH:mm:ss.MS,默认时间分辨率为毫秒。比如:2017-08-12 18:25:58.128 - 内部函数 NOW 是客户端的当前时间
- 插入记录时,如果时间戳为 NOW,插入数据时使用提交这条记录的客户端的当前时间
- Epoch Time:时间戳也可以是一个长整数,表示从 UTC 时间 1970-01-01 00:00:00 开始的毫秒数。相应地,如果所在 Database 的时间精度设置为“微秒”,则长整型格式的时间戳含义也就对应于从 UTC 时间 1970-01-01 00:00:00 开始的微秒数;纳秒精度逻辑相同。
- 时间可以加减,比如 NOW-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。比如
SELECT * FROM t1 WHERE ts > NOW-2w AND ts <= NOW-1w,表示查询两周前整整一周的数据。在指定降采样操作(Down Sampling)的时间窗口(Interval)时,时间单位还可以使用 n(自然月)和 y(自然年)。
TDengine TSDB 缺省的时间戳精度是毫秒,但通过在 CREATE DATABASE 时传递的 PRECISION 参数也可以支持微秒和纳秒。
CREATE DATABASE db_name PRECISION 'ns';
DECIMAL
DECIMAL 数据类型用于高精度数值存储,定义语法:DECIMAL(18, 2)、DECIMAL(38, 10),其中需要指定两个参数,分别为 precision 和 scale。precision 是指最大支持的有效数字个数,scale 是指最大支持的小数位数。如 DECIMAL(8, 4),可表示范围即 [-9999.9999, 9999.9999]。定义 DECIMAL 数据类型时,precision 范围为:[1, 38],scale 的范围为:[0, precision],scale 为 0 时,仅表示整数。也可以不指定 scale,默认为 0,例如 DECIMAL(18),与 DECIMAL(18, 0) 相同。
当 precision 值不大于 18 时,内部使用 8 字节存储 (DECIMAL64),当 precision 范围为 (18, 38] 时,使用 16 字节存储 (DECIMAL)。SQL 中写入 DECIMAL 类型数据时,可直接使用数值写入,当写入值大于类型可表示的最大值时会报 DECIMAL_OVERFLOW 错误,当未大于类型表示的最大值,但小数位数超过 SCALE 时,会自动四舍五入处理。如定义类型 DECIMAL(10, 2),写入 10.987,则实际存储值为 10.99。
DECIMAL 类型仅支持普通列,暂不支持 tag 列。DECIMAL 类型支持 SQL 和 stmt2 写入,暂不支持 schemeless 写入。
整数类型和 DECIMAL 类型操作时,会将整数类型转换为 DECIMAL 类型再进行计算。DECIMAL 类型与 DOUBLE/FLOAT/VARCHAR/NCHAR 等类型计算时,转换为 DOUBLE 类型进行计算。
查询 DECIMAL 类型表达式时,若计算的中间结果超出当前类型可表示的最大值时,报 DECIMAL OVERFLOW 错误。
BLOB
BLOB是一种存储二进制数据的数据类型,最大长度为 4,194,304 字节,可以通过 SQL 或 STMT2 方式写入二进制数据(也可以转换为 \x 开头的字符串写入)。
通过 SHELL 查询数据时,显示为 16 进制的字符串,以 \x 开头。
限制:
- 仅支持在普通数据列中使用 BLOB 类型,BLOB 列数目不能超过 1 个
- 不支持 BLOB 列的条件过滤
短期限制:
- 不支持虚拟表/流计算等功能
JSON
语法说明
-
创建 json 类型 tag
create stable s1 (ts timestamp, v1 int) tags (info json)
create table s1_1 using s1 tags ('{"k1": "v1"}') -
json 取值操作符 ->
select * from s1 where info->'k1' = 'v1'
select info->'k1' from s1 -
json key 是否存在操作符 contains
select * from s1 where info contains 'k2'
select * from s1 where info contains 'k1'
支持的操作
-
在 where 条件中时,支持函数
match、nmatch、between and、like、and、or、is null、is not null,不支持inselect * from s1 where info->'k1' match 'v*';
select * from s1 where info->'k1' like 'v%' and info contains 'k2';
select * from s1 where info is null;
select * from s1 where info->'k1' is not null -
支持 json tag 放在 group by、order by、join 子句、union all 以及子查询中,比如 group by json->'key'
-
支持 distinct 操作
select distinct info->'k1' from s1 -
标签操作
支持修改 json 标签值(全量覆盖)
支持修改 json 标签名
不支持添加 json 标签、删除 json 标签、修改 json 标签列宽
其他约束条件
-
只有标签列可以使用 json 类型,如果用 json 标签,标签列只能有一个。
-
长度限制:json 中 key 的长度不能超过 256,并且 key 必须为可打印 ascii 字符;json 字符串总长度不超过 4096 个字节。
-
json 格式限制:
- json 输入字符串可以为空(""、"\t"、" " 或 null)或 object,不能为非空的字符串,布尔型和数组。
- object 可为 ,如果 object 为 ,则整个 json 串记为空。key 可为 "",若 key 为 "",则 json 串中忽略该 k-v 对。
- value 可以为数字 (int/double) 或字符串或 bool 或 null,暂不可以为数组。不允许嵌套。
- 若 json 字符串中出现两个相同的 key,则第一个生效。
- json 字符串里暂不支持转义。
-
当查询 json 中不存在的 key 时,返回 NULL
-
当 json tag 作为子查询结果时,不再支持上层查询继续对子查询中的 json 串做解析查询。
比如暂不支持
select jtag->'key' from (select jtag from stable)不支持
select jtag->'key' from (select jtag from stable) where jtag->'key'>0
常量
TDengine TSDB 支持多个类型的常量,细节如下表:
| # | 语法 | 类型 | 说明 |
|---|---|---|---|
| 1 | [{+ | -}]123 | BIGINT | 整型数值的字面量的类型均为 BIGINT。如果用户输入超过了 BIGINT 的表示范围,TDengine 按 BIGINT 对数值进行截断。 |
| 2 | 123.45 | DOUBLE | 浮点数值的字面量的类型均为 DOUBLE。TDengine 依据是否存在小数点,或使用科学计数法表示,来判断数值类型是否为整型或者浮点型。 |
| 3 | 1.2E3 | DOUBLE | 科学计数法的字面量的类型为 DOUBLE。 |
| 4 | 'abc' | BINARY | 单引号括住的内容为字符串字面值,其类型为 BINARY,BINARY 的 Size 为实际的字符个数。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 \'。 |
| 5 | "abc" | BINARY | 双引号括住的内容为字符串字面值,其类型为 BINARY,BINARY 的 Size 为实际的字符个数。对于字符串内的双引号,可以用转义字符反斜线加单引号来表示,即 \"。 |
| 6 | TIMESTAMP {'literal' | "literal"} | TIMESTAMP | TIMESTAMP 关键字表示后面的字符串字面量需要被解释为 TIMESTAMP 类型。字符串需要满足 YYYY-MM-DD HH:mm:ss.MS 格式,其时间分辨率为当前数据库的时间分辨率。 |
| 7 | {TRUE | FALSE} | BOOL | 布尔类型字面量。 |
| 8 | {'' | "" | '\t' | "\t" | ' ' | " " | NULL } | -- | 空值字面量。可以用于任意类型。 |
- TDengine TSDB 依据是否存在小数点,或使用科学计数法表示,来判断数值类型是否为整型或者浮点型,因此在使用时要注意相应类型越界的情况。例如,9999999999999999999 会认为超过长整型的上边界而溢出,而 9999999999999999999.0 会被认为是有效的浮点数。







