一、说明
TDengine (TSDB) 的 SQL 语法与标准 SQL 相似,但其**"超级表"(STable)和子表(Table)** 的设计是其核心。你可以将超级表理解为一个设备或数据流的模板(定义表结构和标签),而子表则是具体的设备实例(注意TDengine 3.x与2.x的语法确实有重要区别,此篇采用3.3.8版本)
二、基本 SQL 使用分为几个核心部分
| 操作大类 | 关键语句/功能 | 核心要点/目的 |
|---|---|---|
| 库与表管理 | CREATE DATABASE, CREATE STABLE, CREATE TABLE |
建立数据容器,定义超级表结构(采集指标和标签),创建设备子表。 |
| 数据写入 | INSERT INTO ... VALUES, INSERT INTO ... USING ... TAGS |
支持单条、批量、多表写入;可使用USING子句在写入时自动建表。 |
| 数据查询 | SELECT, WHERE, GROUP BY, ORDER BY |
基础查询,支持条件过滤、聚合、排序。 |
| 时序特色查询 | INTERVAL(时间窗口), SLIDING(滑动窗口), FILL(数据填充) |
核心时序功能,用于降采样、滑动平均、数据插值等。 |
| 数据维护 | DELETE, DROP, ALTER |
删除数据记录、删除表/库、修改表结构。 |
三、TDengine 3.3.8 版本的基本 SQL 语法
| 类别 | 核心操作/语句 | 主要用途与说明 |
|---|---|---|
| 库操作 | CREATE DATABASE |
创建库,3.x关键参数 :DAYS_PER_FILE, BUFFER |
ALTER DATABASE |
修改库参数 | |
DROP DATABASE |
删除库 | |
| 超级表操作 | CREATE STABLE |
定义数据模型 :含数据列和标签列(TAGS) |
ALTER STABLE |
修改超级表结构(增/删标签) | |
| 子表操作 | CREATE TABLE ... USING ... TAGS (...) |
基于超级表创建具体设备表 |
INSERT ... USING ... TAGS (...) |
写入时自动建子表 | |
| 数据写入 | INSERT INTO ... VALUES |
支持单条/批量写入 |
| 数据查询 | SELECT ... FROM ... |
基础查询 ,支持WHERE, GROUP BY, ORDER BY, LIMIT等 |
SELECT ... FROM stb_name |
超级表聚合查询 ,核心是INTERVAL()时间窗口 |
|
... INTERVAL(...) SLIDING(...) |
时序特色:滑动窗口 | |
... FILL(...) |
时序特色:数据缺失填充 | |
| 数据维护 | INSERT (相同时间戳) |
覆盖更新数据 |
DELETE FROM ... |
删除数据 | |
| 用户与权限 | CREATE USER, GRANT |
用户管理与权限控制 |
四. 数据库操作
sql
-- 创建数据库
CREATE DATABASE mydb PRECISION 'ms' KEEP 3650 DURATION 10 BUFFER 96;
-- 使用/切换数据库
USE mydb;
-- 修改数据库参数
ALTER DATABASE mydb BUFFER 128;
-- 删除数据库(谨慎!)
DROP DATABASE mydb;
| 参数 | 值示例 | 含义与作用 | 说明与注意事项 |
|---|---|---|---|
PRECISION |
'ms' |
时间戳精度:指定数据库中时间戳的存储单位。 | 可选 'us'(微秒), 'ns'(纳秒,企业版支持)。一旦设定,不可更改。 |
KEEP |
3650 |
数据保留天数:单份数据文件在数据库中的最长保存时间。 | 超过此天数的数据文件会被自动删除。这是数据保留的主控制参数。 |
DURATION |
10 |
文件持续时间:单个数据文件存储多少天的数据。 | 此参数与 KEEP 协同工作,用于控制数据文件的粒度与数量。 |
BUFFER |
96 |
写入内存缓冲区大小(MB):每个Vnode用于暂存写入数据的内存池。 | 影响写入性能和内存占用。值越大,突发写入能力越强,但消耗内存越多。 |
4.1 核心参数详解与配置策略
1. PRECISION 'ms':时间戳精度
这个参数决定了时间戳字段的最小单位。
-
'ms'(毫秒):最常用设置,适用于绝大多数监控场景(如每秒采集一次)。
-
'us'(微秒):适用于高频交易、精密仪器等需要微秒级时间记录的场景。
-
重要提示 :此参数在数据库创建后无法修改。如果你的应用未来可能需要更高精度,建议提前规划。
2. KEEP 3650 与 DURATION 10:数据保留与文件管理
这两个参数必须放在一起理解,它们共同管理数据的生命周期和存储结构。
-
KEEP(总保留期) :定义了数据的"最长寿命"。例如KEEP 3650表示数据最多保存10年,到期后文件会被系统自动清理。 -
DURATION(文件粒度) :定义了数据文件的"大小"。例如DURATION 10表示每10天的数据会独立存为一个文件。 -
协同工作示例 :
KEEP 3650 DURATION 10意味着:-
系统将每10天的数据打包成一个文件。
-
同时,系统最多保留约
3650 / 10 = 365个这样的文件。 -
当有新的10天数据文件产生时,最旧的那个文件会被删除,始终维持约365个文件。
-
-
调整建议:
-
DURATION值越小,单个文件越小,查询特定时间范围可能更快,但文件总数会变多。 -
通常建议
DURATION是KEEP的 1/10 到 1/100 。对于长期存储(KEEP值大),DURATION也可以相应增大。
-
3. BUFFER 96:写入性能调节器
-
作用机制:数据写入时,先进入此内存缓冲区,缓冲区满后才会批量、顺序写入磁盘。这是TDengine实现高效写入的关键。
-
取值建议:
-
96(MB)是一个通用默认值。 -
对于写入吞吐量极高 的场景,可适当调大(如
256或512),以平滑写入波动,提升性能。 -
在内存有限 或Vnode数量极多的环境下,需调小以防内存耗尽。
-
4.2 配置实例与建议
假设一个物联网平台,有10万台设备,每30秒上报一次数据。
-
基础配置:
sqlCREATE DATABASE mydb PRECISION 'ms' -- 毫秒精度足够 KEEP 1095 -- 保留3年历史数据 DURATION 30 -- 每30天一个数据文件(3年约有36个文件) BUFFER 128; -- 中等写入负载,128MB缓冲区 -
高性能写入场景(如金融高频数据):
sqlCREATE DATABASE trade_market PRECISION 'us' -- 需要微秒级时间记录 KEEP 365 -- 保留1年 DURATION 10 -- 每10天一个文件 BUFFER 256; -- 较大的缓冲区应对突发写入 -
修改现有数据库参数 (使用
ALTER DATABASE):sql-- 可以调整 BUFFER, KEEP, DURATION 等参数(PRECISION除外) ALTER DATABASE mydb BUFFER 256; ALTER DATABASE mydb KEEP 1800 DURATION 15;
4.3 总结
-
PRECISION:按需选择。 -
KEEP和DURATION:联合设定数据保存策略和存储粒度,影响查询效率与文件数量。 -
BUFFER:根据写入负载和内存资源动态调整,是重要的性能调优参数。
五. 超级表操作
超级表是核心模型,定义数据结构和设备标签
sql
-- 创建超级表
CREATE STABLE devices (
ts TIMESTAMP, -- 【必须】时间戳主键
temperature FLOAT, -- 采集指标1
humidity INT, -- 采集指标2
status BINARY(10) -- 采集指标3
) TAGS (
device_id BINARY(64), -- 设备ID标签
region NCHAR(20), -- 地域标签
group_id INT -- 组标签
);
-- 查看超级表定义
DESCRIBE devices;
-- 修改超级表(如增加标签)
ALTER STABLE devices ADD TAG `comment` BINARY(100);
ALTER STABLE devices DROP TAG `comment`;
六、子表操作
子表通过超级表模板创建,代表具体设备。
sql
-- 显式创建子表(为设备'd1001'建表)
CREATE TABLE d1001 USING devices TAGS ('device_001', 'cangzhou', 1);
--【常用】写入时自动创建子表
INSERT INTO d1002 USING devices TAGS ('device_002', 'tianjin', 2) VALUES (NOW, 25.3, 50, 'normal');
-- 查看子表信息(如标签值)
SELECT * FROM INFORMATION_SCHEMA.INS_TAGS WHERE TABLE_NAME='d1001';
七、数据写入
sql
-- 写入单条数据
INSERT INTO d1001 VALUES ('2026-01-21 00:00:00.000', 23.5, 60, 'normal');
--【高效】批量写入(多条VALUES用空格分隔)
INSERT INTO d1001 VALUES
('2026-01-21 00:00:10.000', 23.8, 61, 'normal')
('2026-01-21 00:00:20.000', 24.1, 59, 'normal');
-- 向多个子表批量写入
INSERT INTO d1001 VALUES ('2026-01-21 00:00:30', 24.0, 62, 'normal')
d1002 VALUES ('2026-01-21 00:00:30', 26.1, 55, 'normal');
八、数据查询
sql
-- 基础查询(与标准SQL类似)
SELECT * FROM d1001 LIMIT 10;
SELECT AVG(temperature), MAX(humidity) FROM d1001
WHERE ts > '2026-01-21' AND ts < '2026-01-22';
-- 超级表聚合查询(核心功能)
-- 按设备标签`device_id`分组计算
SELECT device_id, AVG(temperature) FROM devices
WHERE group_id = 1
GROUP BY device_id;
-- 时序特色查询:时间窗口聚合(INTERVAL)
-- 每1小时计算一次平均温度
SELECT _WSTART, _WEND, AVG(temperature) FROM devices
WHERE region='cangzhou'
INTERVAL(1h); -- 时间窗口子句
-- 时序特色查询:滑动窗口(SLIDING)
-- 每5分钟计算一次过去10分钟的滑动平均
SELECT _WSTART, AVG(temperature) FROM devices
INTERVAL(10m) SLIDING(5m);
-- 时序特色查询:数据填充(FILL)
-- 在1小时窗口内,如果无数据,用前一个值填充
SELECT _WSTART, AVG(temperature) FROM devices
INTERVAL(1h) FILL(PREV);
-- 获取子表名(TBNAME)与标签值
SELECT TBNAME, device_id, ts, temperature FROM devices;
九、数据更新与删除
sql
-- 数据更新(通过相同时间戳写入新值覆盖)
INSERT INTO d1001 (ts, temperature) VALUES ('2026-01-21 00:00:00', 256.0);
-- 删除数据(谨慎!可基于时间戳和标签条件)
DELETE FROM devices WHERE ts < '2026-01-22'; -- 删除超级表下旧数据
DELETE FROM d1001 WHERE ts = '2026-01-01 00:00:00';
十、用户与权限管理
sql
-- 创建用户
CREATE USER admin PASS 'your_secure_password';
-- 授予权限
GRANT ALL PRIVILEGES ON mydb.* TO admin; -- 所有权限
GRANT READ ON mydb.* TO user1; -- 只读权限
-- 收回权限
REVOKE ALL PRIVILEGES ON mydb.* FROM user1;
十一、重要提醒
版本差异 :你遇到的语法错误,核心是3.x将
DAYS改为DAYS_PER_FILE。另一个常见区别是CACHEMODEL参数在3.x中已移除。语句长度:单个SQL语句最大长度为1MB,写入时需合理规划批量大小。
性能核心:
务必使用批量写入(多行VALUES)。
对超级表查询时,尽量在
WHERE中使用标签字段过滤,效率远高于时间后过滤。合理规划
INTERVAL窗口长度,平衡查询效率与数据精度。
十二、官方文档
遇到不确定的语法或函数,最权威的参考是 TDengine 3.0 官方SQL手册