TDengine SQL 完全指南:语法约定、数据类型、建库建表与查询体系全景解析
【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine
本文围绕 TDengine 3.x 的核心交互语言 TDengine SQL 展开,系统讲解其语法书写约定、内置数据类型与时间精度体系、建库(CREATE DATABASE)与建表(CREATE TABLE)的关键参数、命名规则与系统限制,以及从 2.x 迁移到 3.x 时必须了解的语法变化。读者读完本文后,将掌握 TDengine SQL 的基本书写规则,能独立完成数据库与(超级)表的设计建模,并具备进一步深入写入、查询、流式计算等高级特性的知识地图。
TDengine SQL 概述:面向时序数据的扩展 SQL
TDengine SQL 是 TDengine 中读写数据的核心工具。它基于标准 SQL,同时为时序数据和业务需求扩展了大量语法特性与函数,覆盖语法规则、数据类型、数据定义(DDL)、数据写入、数据查询、函数以及常见限制等完整链路。使用它之前,读者应具备基础的 SQL 知识;若正在从 2.x 迁移到 3.x,建议同时查阅文档 3.0 语法变化,其中列出了被废弃的语法及其替代方案。
TDengine SQL 有以下两个值得注意的全局特性:
- 语句长度上限可配置:默认情况下单条 TDengine SQL 语句的最大长度为 4 MB,可通过客户端参数
maxSQLLength配置,取值范围为 1 MB 到 64 MB。 - 不支持关键字缩写:例如
DELETE不能缩写为DEL,必须书写完整关键字。
SQL 语法书写约定
TDengine SQL 文档中的语法描述遵循以下统一约定,理解这些约定是正确阅读和使用官方语法图的前提:
| 约定 | 含义 |
|---|---|
| 大写字母 | 表示关键字(Keyword),但 SQL 本身对关键字和标识符不区分大小写 |
| 小写字母 | 表示需要用户自行填写的内容 |
方括号[ ] | 表示可选内容,但输入时不能键入[]本身 |
| | 表示多选一,从中选择一项,但输入时不能键入|本身 |
... | 表示前一项可以重复多次 |
例如,CREATE DATABASE [IF NOT EXISTS] db_name表示IF NOT EXISTS是可选的,而db_name是必须由用户提供的库名。仓库中的 SQL 词法与语法解析实现位于 source/libs/parser(包含.y语法文件),解析器生成器 lemon 位于 contrib/lemon,读者可结合源码理解上述约定在实现层面的落地。
贯穿全章的示例数据集:智能电表建模
为了便于说明 SQL 语法规则与特性,TDengine SQL 文档全章节统一采用"智能电表"作为示例数据集:假设每只智能电表采集三项指标——电流(current)、电压(voltage)和相位(phase)。其建模结构如下:
taos> DESCRIBE meters; Field | Type | Length | Note | ========================================= ts | TIMESTAMP | 8 | | current | FLOAT | 4 | | voltage | INT | 4 | | phase | FLOAT | 4 | | location | BINARY | 64 | TAG | groupid | INT | 4 | TAG |该数据集包含 4 只智能电表的数据。按照 TDengine 建模规则,它们对应 4 张子表,分别命名为d1001、d1002、d1003和d1004;后续示例统一使用groupid作为分组标签(tag)名。这一"超级表(STABLE)+ 子表"的建模范式是 TDengine 区别于普通关系数据库的核心所在,详细语法见 超级表文档。
数据类型与时间精度体系
TDengine 普通表、子表和超级表可使用的数据类型如下表所示,部分类型对使用位置有特殊限制(如JSON只能用于标签列)。
| 类型 | 存储 | 说明 |
|---|---|---|
TIMESTAMP | 8 字节 | 时间戳。默认精度为毫秒,可在建库时设置为微秒或纳秒 |
BOOL | 1 字节 | 布尔型 |
TINYINT | 1 字节 | 有符号单字节整数,范围[-128, 127] |
TINYINT UNSIGNED | 1 字节 | 无符号单字节整数,范围[0, 255] |
SMALLINT | 2 字节 | 有符号短整数,范围[-32768, 32767] |
SMALLINT UNSIGNED | 2 字节 | 无符号短整数,范围[0, 65535] |
INT | 4 字节 | 有符号整数,范围[-2^31, 2^31-1] |
INT UNSIGNED | 4 字节 | 无符号整数,范围[0, 2^32-1] |
BIGINT | 8 字节 | 有符号长整数,范围[-2^63, 2^63-1] |
BIGINT UNSIGNED | 8 字节 | 无符号长整数,范围[0, 2^64-1] |
FLOAT | 4 字节 | 单精度浮点数,约 6–7 位有效数字,范围约[-3.4E38, 3.4E38] |
DOUBLE | 8 字节 | 双精度浮点数,约 15–16 位有效数字,范围约[-1.7E308, 1.7E308] |
BINARY | 自定义 | 单字节字符串,建议仅存 ASCII 可打印字符 |
VARCHAR | 自定义 | BINARY的别名 |
NCHAR | 自定义 | 多字节字符串,适合中文等多字节字符 |
VARBINARY | 自定义 | 变长二进制数据 |
GEOMETRY | 自定义 | 几何类型,支持二维POINT、LINESTRING、POLYGON |
DECIMAL | 8 或 16 字节 | 高精度数值类型,范围取决于precision与scale |
BLOB | 最大 4 MB | 大对象二进制数据 |
JSON | 自定义 | JSON 标签类型,只能用于标签列 |
主要通用限制包括:单行数据最大 48 KB(3.0.5.0 起为 64 KB),且每个BINARY/NCHAR/GEOMETRY/VARBINARY列额外占用 2 字节存储;BINARY、VARBINARY、GEOMETRY数据列最大长度 65,517 字节、标签列最大 16,382 字节;JSON标签一旦使用则只能有一个标签列;DECIMAL目前仅支持普通列。
时间单位
凡是 TDengine SQL 需要时间长度的地方(时间运算、INTERVAL、EVERY、SLIDING等),使用单个字符后缀表示单位:
| 单位 | 含义 | 说明 |
|---|---|---|
b | 纳秒 | 最小精度单位,仅当数据库精度为纳秒时有意义 |
u | 微秒 | 仅当数据库精度为微秒或纳秒时有意义 |
a | 毫秒 | 数据库默认精度 |
s | 秒 | |
m | 分钟 | |
h | 小时 | |
d | 天 | |
w | 周 | 固定为 7 天 |
n | 自然月 | 日历单位,仅允许在INTERVAL窗口中使用 |
q | 自然季度 | 日历单位,等于 3 个自然月,仅允许在INTERVAL窗口中使用 |
y | 自然年 | 日历单位,仅允许在INTERVAL窗口中使用 |
单位字母不区分大小写,例如1S与1s等价。完整时区与自然单位语义参见 时区与自然时间单位。
时间戳
时间戳是时序数据的主键。建表、写数据、查历史数据通常都要指定时间戳:
- 时间字符串格式为
YYYY-MM-DD HH:mm:ss.MS,默认分辨率为毫秒,如2017-08-12 18:25:58.128。 NOW表示客户端当前时间;写入时若时间戳为NOW,则使用提交客户端的当前时间。- 时间戳也可以是自 UTC
1970-01-01 00:00:00以来的长整数,其单位跟随数据库精度(毫秒/微秒/纳秒)。 - 时间表达式支持加减运算,如
NOW - 2h表示两小时前。
默认时间戳精度为毫秒,建库时可通过PRECISION设置为微秒或纳秒:
CREATE DATABASE db_name PRECISION 'ns';DECIMAL、BLOB 与 JSON 标签
- DECIMAL:定义语法为
DECIMAL(18, 2)、DECIMAL(38, 10)等形式,其中precision为最大有效数字位数(范围[1, 38]),scale为最大小数位数(范围[0, precision],缺省为 0)。precision ≤ 18时占用 8 字节(DECIMAL64),(18, 38]时占用 16 字节。例如类型DECIMAL(10, 2)写入10.987会存储为10.99;超出最大值报DECIMAL_OVERFLOW。DECIMAL 支持 SQL 与 STMT2 写入,暂不支持 schemaless 写入。 - BLOB:最大长度 4,194,304 字节,可通过 SQL 或 STMT2 写入,或以
\x开头的字符串形式写入;shell 查询时以\x开头的十六进制字符串展示。BLOB 只能出现在普通数据列中且至多一列,不支持条件过滤,也不支持虚拟表、流计算等特性。 - JSON 标签:只能用于标签列且全表只能有一个。支持
->取值操作符与CONTAINS键存在性判断,例如:
CREATE STABLE s1 (ts TIMESTAMP, v1 INT) TAGS (info JSON); CREATE TABLE s1_1 USING s1 TAGS ('{"k1": "v1"}'); SELECT * FROM s1 WHERE info->'k1' = 'v1'; SELECT * FROM s1 WHERE info CONTAINS 'k2';常量形式
TDengine 支持整数(如123、-123,类型BIGINT)、浮点数(如123.45,类型DOUBLE)、科学计数法(如1.2E3)、字符串(如'abc',内部单引号用\'转义)、时间戳字面量(TIMESTAMP '2017-08-12 18:25:58.128')、布尔(TRUE/FALSE)以及空值(空串、制表符、空格或NULL)等常量形式。注意溢出陷阱:9999999999999999999会溢出长整数上界,而9999999999999999999.0是合法的浮点数。
完整数据类型说明见 数据类型与精度。
建库 DDL:CREATE DATABASE 关键参数
CREATE DATABASE用于创建数据库,其完整语法如下(仅列出主要选项):
CREATE DATABASE [IF NOT EXISTS] db_name [database_options] database_option: { VGROUPS value | PRECISION {'ms' | 'us' | 'ns'} | REPLICA value | REPLICAS value | BUFFER value | PAGES value | PAGESIZE value | CACHEMODEL {'none' | 'last_row' | 'last_value' | 'both'} | CACHESIZE value | COMP {0 | 1 | 2} | DURATION value | MAXROWS value | MINROWS value | KEEP value | SCHEMALESS {0 | 1} | STT_TRIGGER value | SINGLE_STABLE {0 | 1} | WAL_LEVEL {1 | 2} | WAL_FSYNC_PERIOD value | ... }以下为核心参数的语义、默认值与取值范围:
| 参数 | 默认值 | 范围 | 说明 |
|---|---|---|---|
VGROUPS | — | — | 数据库初始 vgroup 数量 |
PRECISION | ms | ms/us/ns | 时间戳精度 |
REPLICA | 1 | 1/2/3 | 副本数,集群中须 ≤ DNODE 数量;REPLICAS是其别名(2 副本仅企业版 3.3.0.0 起可用) |
BUFFER | 256 | [3, 16384] | VNODE 写入内存池大小,单位 MB |
PAGES | 256 | ≥ 64 | VNODE 元数据存储引擎缓存页数 |
PAGESIZE | 4 | [1, 16384] | 元数据存储引擎页大小,单位 KB |
CACHEMODEL | none | 见左 | 是否缓存子表最新数据:last_row显著提升LAST_ROW性能,last_value提升LAST性能,both同时开启 |
CACHESIZE | 1 | [1, 65536] | 每个 vnode 缓存子表最新数据的内存,单位 MB |
COMP | 2 | [0, 2] | 压缩级别:0 不压缩、1 一级压缩、2 两级压缩 |
DURATION | 10d | [60m, 3650d] | 数据文件存储时间跨度,支持 m/h/d 单位 |
MAXROWS | 4096 | — | 文件块最大记录数 |
MINROWS | 100 | — | 文件块最小记录数 |
KEEP | 3650 | [1, 365000] | 数据文件保留天数,须 ≥ 3 倍DURATION,支持带单位写法 |
SCHEMALESS | — | 0/1 | 是否允许 schemaless 写入 |
WAL_LEVEL | 1 | 1/2 | 1 写 WAL 但不 fsync;2 写 WAL 并 fsync |
WAL_FSYNC_PERIOD | 3000 | [0, 180000] | WAL_LEVEL=2时的落盘周期,单位毫秒,0 表示每次写入立即落盘 |
需要特别说明的几个参数:
- KEEP 与多级存储:
KEEP可带单位(KEEP 100h、KEEP 10d),也可不带单位(默认天)。企业版支持多级存储,可设置最多 3 个保留时间(如KEEP 100h,100d,3650d,满足 keep0 ≤ keep1 ≤ keep2);社区版不支持多级存储,即使配置多个保留时间也仅按最长保留时间生效。KEEP_TIME_OFFSET(3.2.0.0 起)用于延迟执行超过KEEP的数据删除/迁移,避免业务高峰期,默认 0 小时。 - CACHESHARDBITS:last-value LRU 缓存的 shard 位数,控制并发缓存访问的锁粒度,默认 -1(自动计算),范围 [-1, 19]。实际 shard 数等于
2^CACHESHARDBITS;自动计算时每个 shard 至少 512 KB,shard 位数上限为 6。修改该参数会立即失效该库所有 vnode 的 last-value 缓存条目,后续查询需从磁盘重新加载,可能短暂增加查询延迟。 - WAL 相关:
WAL_RETENTION_PERIOD(默认 3600 秒)与WAL_RETENTION_SIZE(默认 0,即不设上限)用于数据订阅场景下 WAL 日志的额外保留策略。
创建数据库的完整示例:
create database if not exists db vgroups 10 buffer 10上述语句创建名为db的数据库,包含 10 个 vgroup,每个 vnode 分配 10 MB 写缓冲。使用/切换当前库用USE db_name;(该语句在 REST 连接下无效)。
删除数据库使用DROP DATABASE [IF EXISTS] db_name,注意该操作会连带删除库内所有表并销毁所有 vgroup。
ALTER DATABASE可动态修改部分参数(如CACHEMODEL、BUFFER、KEEP、WAL_LEVEL等)。修改副本数时还可指定PARALLEL控制并发度:ALTER DATABASE db_name REPLICA 3 [PARALLEL parallel_value],其中parallel_value为 0 表示不限并发(最快)、1 表示串行(最省资源)、N 表示最多 N 个 vgroup 并发。PARALLEL仅适用于修改REPLICA,不能与其他 ALTER 选项共用。完整参数列表见 数据库 DDL 文档。
建表 DDL:CREATE TABLE、超级表与子表
CREATE TABLE用于创建普通表、以超级表为模板创建子表,以及通过TAGS子句创建超级表或带自有标签的普通表:
CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definition] ...) [table_options] CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definition] ...) [TAGS (tag_def [, tag_def] ...)] [table_options] create_subtable_clause: { create_subtable_clause [create_subtable_clause] ... | [IF NOT EXISTS] [db_name.]tb_name USING [db_name.]stb_name [(tag_name [, tag_name] ...)] TAGS (tag_value [, tag_value] ...) }建表要点:
- 表名最长 192 字符,命名规则见 命名规则。
- 表的第一列必须是
TIMESTAMP,系统自动将其设为主键。 - 除时间戳主键外,可用
COMPOSITE KEY关键字将第二列指定为复合主键列,该列必须是INT、BIGINT、INT UNSIGNED、BIGINT UNSIGNED或VARCHAR、BINARY等类型。 TAGS子句的语义取决于标签是否带值:所有标签均无值时创建超级表;每个标签都带显式= const_value时创建带自有标签的普通表(= NULL也是合法的显式值);混用带值与不带值的标签会被拒绝。普通表自有标签仅支持字面量值,且DECIMAL类型不支持作为标签。
-- 带自有标签的普通表 CREATE TABLE ntb (ts TIMESTAMP, v INT) TAGS (loc INT = 5, dept VARCHAR(16) = 'rd');表级选项包括:
- COMMENT:表注释,最长 1024 字节,可用于超级表、子表和普通表。
- SMA(Small Materialized Aggregates):基于数据块的预计算以加速聚合查询,预计算类型包括 MAX、MIN、SUM。默认系统会为大多数列创建块级 SMA;若在建表时指定
SMA(col_name, ...),则仅为所列列创建。 - TTL:表生命周期,单位天,范围 [0, 2147483647],默认 0 表示不限。超过 TTL 后系统会自动(近似地)删除该表。注意 TTL 与数据库
KEEP参数无关,若KEEP小于TTL,数据可能先于表被删除。
CREATE TABLE详细语法与ALTER TABLE维护操作见 表 DDL 文档。
命名规则与系统限制
命名规则:数据库、表、列、标签名只能包含英文字母、数字和下划线,可以字母或下划线开头,不能以数字开头,不区分大小写,且不能是保留关键字。
TDengine 还提供反引号转义以支持更自由的命名:转义后名称保留用户指定的大小写(`aBc`与`abc`是不同的名字)、可包含字母数字下划线以外的字符(但不能含.)、可以数字开头(如`1970`)、也可以使用保留关键字(如`select`)。
密码字符集:合法字符集为[a-zA-Z0-9!?$%^&*()_-+={[}]:;@~#|<,>.?/],禁止单引号、双引号、反引号、反斜杠和空格。
常用系统限制(详见 命名与限制):
- 数据库名最长 64 字节;表名最长 192 字节(不含库名前缀与分隔符);列名、标签名最长 64 字节。
- 每行数据最长 48 KB(3.0.5.0 起 64 KB);最多 4096 列、最少 2 列,首列必须是时间戳;最多 128 个标签、至少 1 个标签,表内标签值总长不超过 16 KB。
- SQL 语句默认最大 4,194,304 字符,可通过
maxSQLLength配置,最大值 64 MB;SELECT 结果最多返回 4096 列。 - 数据库、超级表、普通表的数量不受系统限制,只受系统资源约束;单个数据库最多 1024 个 vgroup。
从 2.x 迁移到 3.x:关键语法变化
若从 2.x 升级,需重点关注以下变化(完整对照表见 3.0 语法变化):
基础元素新增:VARCHAR作为BINARY别名;TIMESTAMP字面量语法;_ROWTS伪列(时间戳主键别名)、_IROWTS伪列;INFORMATION_SCHEMA与PERFORMANCE_SCHEMA系统库;GEOMETRY类型;连续查询(Continuous Query)被废弃,由更通用的流式计算替代。
建库参数调整:2.x 的DAYS被DURATION取代(并支持带单位);BLOCKS/CACHE被BUFFER取代;CACHELAST被CACHEMODEL取代;FSYNC被WAL_FSYNC_PERIOD取代;WAL被WAL_LEVEL取代;QUORUM在 3.0 中默认强一致;新增VGROUPS、PAGES、PAGESIZE、RETENTIONS、SINGLE_STABLE等参数;3.0 所有数据库均支持部分列更新(UPDATE参数被移除)。
语句层面:新增CREATE STREAM、CREATE TOPIC、CREATE INDEX(SMA 索引)、GRANT/REVOKE、EXPLAIN、DROP CONSUMER GROUP等语句;ALTER TABLE/ALTER STABLE中CHANGE tag改为RENAME tag,并新增COMMENT、TTL等选项;SHOW DATABASES/SHOW TABLES/SHOW STABLES在 3.0 只显示名称。
SELECT 增强:关闭隐式结果列,输出列必须由 SELECT 子句显式指定;DISTINCT功能全面支持;JOIN、子查询(嵌套层数不限)、GROUP BY(支持任意标量表达式)、ORDER BY(支持NULLS FIRST/LAST)均显著增强;新增PARTITION BY语法取代原来的GROUP BY tags;无PARTITION BY时超级表数据合并为一条时间线,SESSION、STATE_WINDOW及TWA、IRATE、DIFF、CSUM、MAVG等函数均可直接用于超级表。
TDengine SQL 能力地图:从写入到查询的完整知识体系
在掌握语法基础与建模能力后,可按以下模块继续深入(均为docs/en/05-tdengine-sql/下的对应文档):
- 数据写入:INSERT 语法、DELETE(含安全删除)、列级压缩
ENCODE/COMPRESS(03-data-write); - 数据查询:SELECT 基本查询、操作符、函数体系、去重(DISTINCT)、JOIN、窗口函数、UDF、缓存查询(Cache Query)、EXPLAIN 执行计划(04-data-query);
- 物化聚合:TSMA(时间序列物化聚合)与 RSMA(降采样存储)(05-materialized-agg);
- 索引与视图:标签索引、视图(06-index-and-view);
- 用户与权限:用户管理、GRANT/REVOKE 授权体系(07-user-and-privilege);
- 集群管理:DNODE/MNODE/QNODE、XNODE、挂载、恢复(08-cluster-management);
- 系统信息:元数据、性能信息、SHOW 命令族(09-system-info);
- 时间语义:时区与夏令时(10-time);
- 附录:转义规则、命名与限制、保留关键字、3.0 语法变化(11-appendix)。
以上模块共同构成 TDengine SQL 的完整能力体系:以本文的语法约定、数据类型与建模 DDL 为基础,向上可延伸至写入、查询、流式计算与集群管理,向下可深入源码(解析器位于 source/libs/parser、执行器位于 source/libs/executor)理解其实现原理。
【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考