TDengine 快速入门实战指南:安装部署、数据建模、写入与查询全流程
【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengine
本指南基于 TDengine 开源仓库的 Quick Start 文档,带你从零完成一次完整的时序数据库体验:先用 Docker 或安装包把 TDengine 跑起来,再用taos命令行和taosBenchmark生成测试数据,最后以智能电表为例,依次掌握数据模型设计(超级表/子表/虚拟表)、SQL 写入、查询聚合、时间窗口分析、数据订阅与流处理。读完本文,你将具备独立搭建 TDengine 环境,并用标准 SQL 完成时序数据"建表—写入—查询—流式处理"闭环的实战能力。
整体架构与文档脉络
TDengine 的完整 TSDB 安装包包含以下核心组件:
- taosd:数据库服务端,负责存储与查询;
- taosAdapter:负责第三方系统集成与 RESTful 访问的适配器;
- taosc:应用程序驱动(客户端库);
- taos:命令行工具 Shell;
- taosExplorer / taoskeeper等配套组件。
除了多语言连接器,TDengine 还通过 taosAdapter 提供 RESTful 接口。官方 Quick Start 建议的路径是:先完成环境安装,然后按"基本概念 → 数据建模 → 数据写入 → 数据查询"的顺序依次实践,再延伸到订阅、流处理与可视化。
安装与部署:三条路径任选
方式一:Docker 部署
从 3.3.7.0 版本起,TDengine 的 Docker 镜像命名发生了变更:社区版tdengine/tdengine更名为tdengine/tsdb,企业版tdengine/tdengine-ee更名为tdengine/tsdb-ee。本指南以企业版镜像为例。
前置条件:机器已安装 Docker 且当前用户有权限执行docker命令;能够访问 Docker Hub(或已从产品下载中心获得离线镜像);确认 网络端口要求 中 TDengine 所需的端口未被占用。
拉取最新企业版镜像:
docker pull tdengine/tsdb-ee:latest也可以拉取指定版本(将{{VERSION}}替换为实际版本号):
docker pull tdengine/tsdb-ee:{{VERSION}}若无法直接访问 Docker Hub,可在 TDengine 产品下载中心下载离线镜像,按页面说明加载后修改镜像名与 tag。
启动容器(关键端口映射一目了然):
docker run -d \ -v ~/data/taos/dnode/data:/var/lib/taos \ -v ~/data/taos/dnode/log:/var/log/taos \ -p 6030:6030 -p 6041:6041 -p 6043:6043 -p 6060:6060 \ -p 6044-6049:6044-6049 \ -p 6044-6045:6044-6045/udp \ -p 6050:6050 -p 6055:6055 \ --name tdengine-tsdb \ tdengine/tsdb-ee这里6030是 taosd 服务端口,6041是 RESTful/taosAdapter 端口,6060是 Explorer 可视化端口。检查容器状态:
docker ps -f name=tdengine-tsdb若输出中STATUS为Up ... (healthy),说明容器已正常启动。随后进入容器:
docker exec -it tdengine-tsdb bash容器内即可直接使用taos、taosBenchmark等工具。更完整的 Docker 部署说明参见 Docker 部署。
方式二:安装包部署(Linux / Windows)
安装前请确认机器满足 支持平台 与 系统要求。Windows 下安装器会检查 Microsoft Visual C++ Redistributable 2015-2022 x64 14.44 及以上版本。
Linux 安装步骤:
- 从产品下载中心下载 tar.gz 安装包;
- 解压(以 x64 架构为例):
tar -zxvf tdengine-tsdb-enterprise-{{VERSION}}-linux-x64.tar.gz- 进入解压后的子目录,执行安装脚本:
sudo ./install.shWindows 安装步骤:运行安装包按提示完成安装,默认安装目录为C:\TDengine;若选择的路径不以TDengine结尾,安装器会在其下创建TDengine目录。升级安装沿用既有目录且不可更改。
启动服务:Linux 下执行sudo start-all.sh启动全部组件,组件由 systemd 管理,可逐一检查状态:
sudo systemctl status taosd sudo systemctl status taosadapter sudo systemctl status taoskeeper sudo systemctl status taos-explorer输出为Active: active (running) since ...即表示启动成功。Windows 下使用start-all.bat管理服务(支持status、stop子命令,-S选项可跳过连通性检查与 Snode/Xnode 初始化),也可用sc query taosd等命令查看各 Windows 服务原始状态。
方式三:TDengine Cloud
TDengine Cloud 是基于 AWS / Azure / GCP 的全托管云服务,注册账号即可获得试用额度,无需自行部署即可体验 TSDB-Enterprise 的全部能力。注册流程包括:访问云平台网站 → 注册邮箱与组织 → 设置密码(8–20 位,须包含字母、数字与特殊字符)→ 选择 TSDB 实例类型、云厂商与区域 → 创建实例。详细步骤见 云服务快速入门。
五分钟快速体验:taos 命令行与 taosBenchmark
部署完成后,可以用taos命令行工具检查服务状态、执行 SQL、管理数据库与表。Linux/macOS 下直接运行taos,Windows 下运行taos.exe,进入 Shell 后提示符为taos>,每条 SQL 必须以分号;结尾。先做一个最小闭环验证:
CREATE DATABASE demo; USE demo; CREATE TABLE t (ts TIMESTAMP, speed INT); INSERT INTO t VALUES ('2019-07-15 00:00:00', 10); INSERT INTO t VALUES ('2019-07-15 01:00:00', 20); SELECT * FROM t;输出示例:
ts | speed | ======================================== 2019-07-15 00:00:00.000 | 10 | 2019-07-15 01:00:00.000 | 20 | Query OK, 2 row(s) in set (0.003128s)用 taosBenchmark 生成百亿级测试数据:taosBenchmark是 TDengine 自带的测试工具,可模拟多设备数据,支持配置数据库、超级表、标签列、数据列、子表数量、每表记录数、写入间隔、worker 线程数以及是否乱序写入。运行:
taosBenchmark -y该命令会在test库中自动创建超级表meters:包含 10,000 个子表(d0–d9999),每表 10,000 条记录,共约 1 亿条。每条记录含ts(时间戳)、current、voltage、phase四个字段,时间戳范围为2017-07-14 10:40:00.000至2017-07-14 10:40:09.999;每表还带location与groupId两个标签。在普通 PC 服务器上写入约需十秒左右。可用taosBenchmark --help查看全部参数,完整参考见 taosBenchmark 参考。
写入后立即体验查询性能:
SELECT COUNT(*) FROM test.meters; -- 输出 100000000,约 0.075s SELECT AVG(current), MAX(voltage), MIN(phase) FROM test.meters; -- 全表 1 亿条记录聚合约 0.094s SELECT COUNT(*) FROM test.meters WHERE location = "California.SanFrancisco"; -- 按标签过滤约 0.05s SELECT _wstart, AVG(current), MAX(voltage), MIN(phase) FROM test.d1001 INTERVAL(10s);其中_wstart是窗口查询的系统伪列,表示每个窗口的起始时间。
核心概念:以智能电表为例
TDengine 文档以智能电表为贯穿全篇的示例:每只电表可采集current(电流)、voltage(电压)、phase(相位)三个指标,同时拥有location(位置)与group_id(分组 ID)两个静态属性。示例数据如下:
| 设备 ID | 时间戳 | 电流 | 电压 | 相位 | 位置 | 分组 |
|---|---|---|---|---|---|---|
| d1001 | 1538548685000 | 10.3 | 219 | 0.31 | California.SanFrancisco | 2 |
| d1002 | 1538548684000 | 10.2 | 220 | 0.23 | California.SanFrancisco | 3 |
| d1003 | 1538548686500 | 11.5 | 221 | 0.35 | California.LosAngeles | 3 |
| d1004 | 1538548685500 | 13.4 | 223 | 0.29 | California.LosAngeles | 2 |
围绕这批数据,需要理解以下核心概念:
- Metric(指标):从传感器、设备等采集点获得的物理量(电流、电压、温度等),随时间变化、持续增长,数据类型多样。
- Tag(标签):与采集点绑定的静态属性(型号、位置等),不随时间增长,可增删改。
- 数据采集点(DCP):按预设周期或事件触发采集指标的硬件/软件设备,同一时刻可采集一个或多个指标(共享同一时间戳)。如汽车可包含定位、发动机状态、车内环境三类采集点。
- Table(表):TDengine 采用"一设备一表"设计,每个采集点对应一张表,表名通常即设备名(如
d1001)。该设计的四大收益:单表单写入者、无锁写入;数据按时间有序、追加式写入;数据块连续存储、减少随机读;块内列式存储、按类型压缩。 - Supertable(超级表):将结构相同、标签不同的采集点聚合为逻辑统一表,解决海量表管理问题。超级表必须含至少一个时间戳列、一个或多个指标列、一个或多个标签列,标签可灵活增删改。
- Subtable(子表):超级表的具体实例,由超级表模板 + 标签值生成。子表结构不可直接修改,但修改超级表列与标签会立即作用于所有子表;超级表本身只定义模板、不存数据。
- Virtual Table(虚拟表):不存储物理数据的逻辑实体,查询时按时间戳动态合并多张源表的列。支持虚拟超级表/虚拟子表/虚拟普通表,不可写入与删除,使"先写入、后建模"成为现实。
- Database(数据库):表的集合容器,一个实例可有多个数据库,各库可配不同存储策略(采集频率、保留期、副本数、数据块大小等),建议将不同数据特征的超级表放入不同数据库。
- Timestamp(时间戳):TDengine 存储 UTC 时间戳。写入时 RFC-3339 格式字符串(如
2018-10-03T14:38:05.000+08:00)按时区正确解析为 UTC;无时区信息的字符串按应用时区转换。查询时客户端按应用时区自动转回本地时间。
数据建模:从建库到虚拟表
创建数据库
CREATE DATABASE power PRECISION 'ms' KEEP 3650 DURATION 10 BUFFER 16;参数含义:PRECISION 'ms'使用毫秒时间精度;KEEP 3650数据保留 3650 天,超期自动删除;DURATION 10每 10 天数据存为一个数据文件;BUFFER 16写入使用 16MB 内存池。创建后执行USE power;切换当前库。
创建超级表
CREATE STABLE meters ( ts timestamp, current float, voltage int, phase float ) TAGS ( location varchar(64), group_id int );规则要点:第一列必须是时间戳列;第二列起为指标列(整型、浮点、字符串等);TAGS后定义标签列,标签名不能与指标列同名。CREATE STABLE等 DDL 语法在仓库的 SQL 解析器 中定义实现。
创建子表
CREATE TABLE d1001 USING meters ( location, group_id ) TAGS ( "California.SanFrancisco", 2 );USING meters表示以超级表meters为模板,TAGS括号内给出该子表的标签值。查询时可用伪列tbname指定或输出子表名。
写入时自动建表
即使子表不存在,也可用带USING的INSERT语句在写入时自动建表:子表不存在则先创建再写入,已存在则直接写入:
INSERT INTO d1002 USING meters TAGS ( "California.SanFrancisco", 2 ) VALUES ( NOW, 10.2, 219, 0.32 );基础表(无标签表)
不依赖超级表的普通表与传统关系表类似,可独立创建:
CREATE TABLE meter_n( ts timestamp, current float, voltage int, phase float, location varchar(64), group_id int );基础表与子表的差异:子表在基础表之上增加了可变标签;子表从属于超级表,基础表独立存在;两者不能互相转换。注意:基础表模型会把静态标签重复存储于每行,既增加存储又无法利用标签过滤,查询性能明显低于超级表模型。
多列模型与单列模型
TDengine 推荐多列模型(同一采集点同一时刻采集的多个物理量存入同一超级表的不同列),写入与存储效率更优;但当采集的物理量类型频繁变化时,单列模型(每种物理量建一张超级表)可避免频繁修改表结构、简化应用设计。
创建虚拟表:两个典型场景
场景一:同源多维时序聚合——将同一采集点"纵向拆分"的多张单列表在虚拟表中恢复为"横向"完整视图。先按单列模型建三张超级表并建子表(current_d1001、voltage_d1001、phase_d1001等),再创建虚拟超级表:
CREATE STABLE meters_v ( ts timestamp, current float, voltage int, phase float ) TAGS ( location varchar(64), group_id int ) VIRTUAL 1;为设备 d1001 创建虚拟子表,将各源表列映射进来:
CREATE VTABLE d1001_v ( current from current_d1001.current, voltage from voltage_d1001.voltage, phase from phase_d1001.phase ) USING meters_v TAGS ( "California.SanFrancisco", 2 );写入原始数据后查询虚拟表SELECT * FROM d1001_v;,TDengine 会按时间戳对齐各源表数据、缺失值以 NULL 填充,例如时间戳1538548697100处只有 current 与 voltage 有值,phase为 NULL:
| 时间戳 | 电流 | 电压 | 相位 |
|---|---|---|---|
| 1538548685000 | 10.3 | 219 | 0.31 |
| 1538548697100 | 12.1 | 220 | NULL |
| 1538548697200 | NULL | NULL | 0.32 |
| 1538548697700 | 11.8 | NULL | NULL |
场景二:跨源指标对比分析——将不同采集点的同类指标横向对齐,例如对比四台设备的电流:
CREATE VTABLE current_v ( ts TIMESTAMP, d1001_current FLOAT FROM current_d1001.current, d1002_current FLOAT FROM current_d1002.current, d1003_current FLOAT FROM current_d1003.current, d1004_current FLOAT FROM current_d1004.current );查询SELECT * FROM current_v;即得到按时间戳对齐的四列电流数据,缺失时间点同样以 NULL 填充。虚拟表的核心特征即"查询时才动态生成数据、只合并查询引用到的列",因此同一虚拟表在不同查询中可呈现完全不同的数据集。
数据写入:SQL 的增删改与压缩查看
写入前先准备好环境(以下 SQL 可在 Shell 中直接执行):
CREATE DATABASE IF NOT EXISTS power PRECISION 'ms' KEEP 3650 DURATION 10 BUFFER 16; USE power; CREATE STABLE IF NOT EXISTS meters ( ts timestamp, current float, voltage int, phase float ) TAGS (location varchar(64), group_id int); CREATE TABLE IF NOT EXISTS d1001 USING meters TAGS ("California.SanFrancisco", 2); CREATE TABLE IF NOT EXISTS d1002 USING meters TAGS ("California.SanFrancisco", 3); CREATE TABLE IF NOT EXISTS d1003 USING meters TAGS ("California.LosAngeles", 2); CREATE TABLE IF NOT EXISTS d1004 USING meters TAGS ("California.LosAngeles", 3);INSERT 的常用形态
单行写入(以下三种写法效果相同):
INSERT INTO d1001 (ts, current, voltage, phase) VALUES ("2018-10-03 14:38:05", 10.3, 219, 0.31); INSERT INTO d1001 VALUES ("2018-10-03 14:38:05", 10.3, 219, 0.31); INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31); -- 数值时间戳(库精度)多行一次写入:
INSERT INTO d1001 VALUES ("2018-10-03 14:38:05", 10.2, 220, 0.23), ("2018-10-03 14:38:15", 12.6, 218, 0.33), ("2018-10-03 14:38:25", 12.3, 221, 0.31);多表一次写入(下例共写入 9 行):
INSERT INTO d1001 VALUES ("2018-10-03 14:38:05", 10.2, 220, 0.23), ("2018-10-03 14:38:15", 12.6, 218, 0.33), ("2018-10-03 14:38:25", 12.3, 221, 0.31) d1002 VALUES ("2018-10-03 14:38:04", 10.2, 220, 0.23), ("2018-10-03 14:38:14", 10.3, 218, 0.25), ("2018-10-03 14:38:24", 10.1, 220, 0.22) d1003 VALUES ("2018-10-03 14:38:06", 11.5, 221, 0.35), ("2018-10-03 14:38:16", 10.4, 220, 0.36), ("2018-10-03 14:38:26", 10.3, 220, 0.33);指定列写入:未出现的列填充 NULL,但时间戳列必须出现且不能为 NULL:
INSERT INTO d1004 (ts, voltage, phase) VALUES ("2018-10-04 14:38:06", 223, 0.29);自动建表 + 多表写入(可只指定部分标签,未指定的为 NULL):
INSERT INTO d1005 USING meters (location) TAGS ("California.SanFrancisco") VALUES ("2018-10-04 14:38:07", 10.15, 217, 0.33);直接向超级表写入:超级表本身不存数据,通过指定tbname将数据落到对应子表:
INSERT INTO meters (tbname, ts, current, voltage, phase, location, group_id) VALUES ("d1001", "2018-10-03 14:38:05", 10.2, 220, 0.23, "California.SanFrancisco", 2);注意:虚拟表是动态生成的逻辑实体、不存储数据,不支持写入。
更新与删除
TDengine 用"同时间戳覆盖写"实现更新,以下 SQL 将d1001在2018-10-03 14:38:05的电流更新为 22:
INSERT INTO d1001 (ts, current) VALUES ("2018-10-03 14:38:05", 22);删除异常数据(删除不可逆,建议先用相同WHERE条件的SELECT确认范围):
DELETE FROM meters WHERE ts < '2021-10-01 10:40:00.100';完整的 INSERT / DELETE 语法与按列压缩配置分别见 数据写入、数据删除、数据压缩。
查看压缩率与磁盘占用
SELECT * FROM INFORMATION_SCHEMA.INS_DISK_USAGE WHERE db_name = 'power'; SHOW TABLE DISTRIBUTED d1001;前者查看数据库级压缩率与磁盘占用,后者查看单表分布与压缩情况。更多信息见 数据库磁盘占用查看 与 SHOW TABLE DISTRIBUTED。
其他写入通道
除 SQL 外,连接器支持 STMT / STMT2 参数绑定实现高吞吐写入(参数绑定);支持 InfluxDB / OpenTSDB 行协议的 Schemaless 写入(可从报文自动建超级表与子表);还可通过 Telegraf、Prometheus、EMQX、StatsD、collectd 等第三方工具实现 无代码数据接入。
数据查询:过滤、聚合与时间窗口分析
TDengine 从首个版本起就支持标准 SQL 查询,并针对时序场景扩展了标签过滤、按设备分区、多类时间窗口、插值与 JOIN 等能力。以下示例基于taosBenchmark -y生成的test库(进入 Shell 后先USE test;)。
基本查询
查询电压大于 250V 的d1子表数据,按时间倒序取前 5 行:
SELECT tbname, ts, current, voltage FROM meters WHERE voltage > 250 and tbname = 'd1' ORDER BY ts DESC LIMIT 5;tbname是标识来源子表的伪列,ORDER BY ts DESC按时间倒序,LIMIT 5只返回前 5 行。
按标签过滤
标签描述设备静态属性,可直接参与过滤,也可与普通列条件组合:
SELECT tbname, ts, current, voltage, phase FROM meters WHERE location = "California.SanFrancisco" AND voltage > 250 ORDER BY ts DESC LIMIT 5;聚合查询
全表聚合返回单行汇总:
SELECT AVG(voltage), MAX(voltage), COUNT(*) FROM meters; -- avg(voltage)=243.9314, max(voltage)=258, count(*)=100000000按标签分组统计:
SELECT groupId, AVG(voltage) AS avg_voltage FROM meters GROUP BY groupId ORDER BY avg_voltage DESC;注意GROUP BY不保证固定顺序,需排序时显式使用ORDER BY。
按子表分区聚合
PARTITION BY tbname先按子表维度切分再各自计算,常用于"每设备统计";用SLIMIT限制返回分区数,避免上万行输出:
SELECT tbname, AVG(voltage), COUNT(*) FROM meters PARTITION BY tbname SLIMIT 3;时间窗口查询
窗口查询把数据按时间、状态、事件或行数切分后再计算。TDengine 支持多种窗口类型:
时间窗口(INTERVAL):按 1 秒窗口计算每表电压均值,_wstart/_wend为窗口起止时间:
SELECT tbname, _wstart, _wend, AVG(voltage) FROM meters WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" PARTITION BY tbname INTERVAL(1s) SLIMIT 2;滑动窗口(SLIDING):窗口 1 秒、每 500 毫秒滑动一次:
SELECT tbname, _wstart, AVG(voltage) FROM meters WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" PARTITION BY tbname INTERVAL(1s) SLIDING(500a) SLIMIT 1;填充缺失窗口(FILL):用前一个非 NULL 值填充无数据的窗口:
SELECT _wstart, _wend, AVG(voltage) FROM d0 WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" INTERVAL(1s) FILL(prev);状态窗口(STATE_WINDOW):状态变化即切窗,如按电压是否处于 240V–250V 划分:
SELECT _wstart, _wend, COUNT(*), CASE WHEN voltage >= 240 AND voltage <= 250 THEN 1 ELSE 0 END AS status FROM d0 WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:03" STATE_WINDOW( CASE WHEN voltage >= 240 AND voltage <= 250 THEN 1 ELSE 0 END ) LIMIT 4;会话窗口(SESSION):按相邻时间戳的间隔切窗,间隔不超过 30 秒的归为同一会话:
SELECT _wstart, _wend, COUNT(*) FROM d0 WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" SESSION(ts, 30s);事件窗口(EVENT_WINDOW):满足开始条件开窗、满足结束条件关窗:
SELECT _wstart, _wend, COUNT(*) FROM d0 WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" EVENT_WINDOW START WITH voltage >= 250 END WITH voltage < 245 LIMIT 4;计数窗口(COUNT_WINDOW):按固定行数分组,如每 100 行一个窗口:
SELECT _wstart, _wend, COUNT(*) FROM d0 WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10" COUNT_WINDOW(100) LIMIT 5;外部窗口(EXTERNAL_WINDOW):窗口边界由子查询(如事件表、排程表)给出,而非自动切分:
SELECT _wstart, _wend, AVG(voltage) FROM d0 EXTERNAL_WINDOW ( (SELECT CAST("2017-07-14 10:40:00" AS TIMESTAMP) AS ws, CAST("2017-07-14 10:40:01" AS TIMESTAMP) AS we UNION ALL SELECT CAST("2017-07-14 10:40:01" AS TIMESTAMP), CAST("2017-07-14 10:40:02" AS TIMESTAMP) ORDER BY ws) w );常用查询模式速查
-- 子表最新一行 SELECT * FROM d0 ORDER BY ts DESC LIMIT 1; -- 按位置统计行数 SELECT location, COUNT(*) FROM meters GROUP BY location ORDER BY location; -- 每表最大电压(SLIMIT 限制返回分区数) SELECT tbname, MAX(voltage) FROM meters PARTITION BY tbname SLIMIT 3; -- 时间范围平均电流 SELECT AVG(current) FROM meters WHERE ts >= "2017-07-14 10:40:00" AND ts < "2017-07-14 10:40:10";查询能力的完整语法与进阶特性(JOIN、窗口函数、UDF、读缓存、执行计划)可继续参考 数据查询、运算符、函数、时序扩展、JOIN、窗口函数、UDF、读缓存 与 EXPLAIN。
数据订阅:像 Kafka 一样消费实时数据
在监控告警、实时分析、数据同步等场景下,下游程序往往需要第一时间拿到新写入的数据。TDengine 内置数据订阅能力,按 topic 把持续写入的数据推送给下游,省去轮询与额外引入消息队列的复杂度。topic 可以是数据库、超级表或既有表上的查询,过滤与预处理由 TDengine 完成;消费者可加入消费组共享进度,数据从 WAL 推送,采用至少一次(at-least-once)投递语义。
以power库的meters超级表为例,第一个 Shell 中创建查询 topic:
CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT tbname, ts, current, voltage, phase FROM meters; SHOW TOPICS; -- 验证 topic 已创建打开第二个 Shell 订阅该 topic:
subscribe topic_meters -g quickstart_cg;其中topic_meters是 topic 名,-g quickstart_cg指定消费组——同组再次订阅时从已提交位置继续消费。执行后 Shell 显示Subscribing to topic [topic_meters], group [quickstart_cg], offset [latest] ...,默认从最新位置开始。回到第一个 Shell 写入两条新数据:
INSERT INTO d1001 VALUES (NOW, 10.3, 219, 0.31); INSERT INTO d1002 VALUES (NOW, 10.2, 220, 0.23);第二个 Shell 中实时输出新写入的两行(tbname、ts、current、voltage、phase)。按Ctrl+C停止订阅,Shell 会打印Unsubscribed. Total rows received: 2。
订阅命令的通用格式为subscribe <topic> -g <group_id> [options];,常用选项:-o earliest从最早可消费位置开始(适合回看存量数据);-o latest从最新位置开始(默认值,适合实时等待新数据);-n <count>收到指定行数后自动退出;-t <timeout_ms>轮询超时。例如:
subscribe topic_meters -g quickstart_cg_earliest -o earliest -n 5; subscribe -h; -- 查看帮助该订阅命令的完整格式同样定义在 Shell 自动补全 中。查看与清理订阅资源:
SHOW TOPICS; SHOW CONSUMERS; SHOW SUBSCRIPTIONS; DROP CONSUMER GROUP IF EXISTS FORCE quickstart_cg ON topic_meters; DROP TOPIC IF EXISTS topic_meters;topic 语法、消费组与原生订阅 API 详见 Topic 语法、原生订阅、MQTT 订阅(自 v3.3.7.0 起可通过连接 Bnode 的 MQTT 客户端订阅已有 topic)与 多语言订阅 API。
流处理:用 SQL 实现实时聚合
传统实时聚合、降采样与提前告警通常需要引入 Kafka、Flink 等流系统。TDengine 自带流处理能力,可以用 SQL 定义实时计算逻辑:数据写入后自动触发计算,结果写入目标表或作为通知发送。核心设计是触发(trigger)与计算(compute)分离,新流处理能力自 v3.3.7.0 起可用。
以test库为例,创建"每分钟计算每只电表平均电流"的流。前置条件是集群中已部署 snode(流任务运行在 snode 上),可用SHOW SNODES;查看,没有则执行SHOW DNODES;与CREATE SNODE ON DNODE 1;部署。
DROP STREAM IF EXISTS avg_current_stream; DROP STABLE IF EXISTS avg_current_stb; CREATE STREAM avg_current_stream INTERVAL(1m) SLIDING(1m) FROM meters PARTITION BY tbname, groupId STREAM_OPTIONS(FILL_HISTORY_FIRST | MAX_DELAY(3s)) INTO avg_current_stb OUTPUT_SUBTABLE(CONCAT("avg_", tbname)) TAGS ( groupId INT AS groupId ) AS SELECT _twstart AS ts, _twend AS window_end, AVG(current) AS avg_current FROM %%trows;各子句含义:INTERVAL(1m) SLIDING(1m)每分钟触发一次计算;FROM meters PARTITION BY tbname, groupId按子表触发并把groupId作为输出标签;STREAM_OPTIONS(FILL_HISTORY_FIRST | MAX_DELAY(3s))先回放已写入的历史数据,窗口打开约 3 秒后也会触发一次(便于快速演示);INTO avg_current_stb结果写入输出超级表;OUTPUT_SUBTABLE(CONCAT("avg_", tbname))由源子表名拼接输出子表名(如d0→avg_d0);%%trows表示当前触发窗口内的数据行集合。
查看流与结果:
SHOW STREAMS; SELECT * FROM information_schema.ins_streams WHERE stream_name = 'avg_current_stream'; SELECT tbname, groupId, ts, window_end, avg_current FROM avg_current_stb ORDER BY ts, tbname LIMIT 5;历史数据(10:40:00–10:41:00窗口)回放完成后,写入新数据观察新窗口:
INSERT INTO d0 VALUES ("2017-07-14 10:41:30", 12.4, 221, 147); INSERT INTO d0 VALUES ("2017-07-14 10:42:00", 12.5, 220, 147); -- 事件时间关闭窗口,无需 MAX_DELAY 也会触发稍候查询avg_d0的输出,可看到10:41:00窗口的avg_current = 12.400000已出现。流会持续运行,只要meters有新数据且满足触发条件就继续计算。清理示例:
DROP STREAM IF EXISTS avg_current_stream; DROP STABLE IF EXISTS avg_current_stb;常用调整:只处理新数据时去掉FILL_HISTORY_FIRST;想更快看到结果可调大/保留MAX_DELAY或在下一窗口写入数据使事件时间关窗;乱序写入、更新删除场景需结合WATERMARK与重算机制设计;需要推送外部应用时用NOTIFY创建通知流。完整语法见 流处理语法,运维与限制见 操作与限制,设计实践见 部署与设计。
更多:可视化、监控与生态集成
- 可视化管理(Explorer):TDengine TSDB Explorer 是基于 Web 的可视化管理工具,适合浏览库表对象、运行 SQL、查看客户端示例与发现集成工具。Docker 方式启动时已映射默认端口
6060,浏览器访问http://localhost:6060(远程主机请替换localhost并确保安全组/防火墙放行)。默认用户名root、密码taosdata;首次登录可能需要先注册。登录后可打开数据浏览页查看数据库、超级表、子表与基础表,并在 SQL 页执行查询。详见 可视化管理。 - Grafana 集成:TDengine 提供 Grafana 插件与数据源,可在 Grafana 中配置 TDengine 数据源、编写查询并制作仪表盘,实现时序监控可视化,参见 Grafana 集成。
- 无代码数据接入:通过 Telegraf、Prometheus、EMQX、StatsD、collectd、HiveMQ 等工具可直接接入数据,企业版还提供 MQTT、OPC、AVEVA PI System、Wonderware、Kafka、MySQL、Oracle 等连接器,配置后无需编写应用代码即可持续写入,见 无代码数据接入。
- Shell 与工具:
taosCLI 与客户端驱动可单独安装到其他机器,使用细节见 TDengine CLI。
继续深入
本文覆盖了快速入门阶段最常用的建库建表、写入、查询、订阅与流处理模式。后续可沿以下方向深入:
- 继续 基本概念、数据建模、数据写入、数据查询 四个章节的完整细节;
- 探索数据订阅(06-data-subscription)与流处理(07-stream-processing)的进阶能力;
- 阅读 TDengine SQL 参考中的 数据写入、数据删除、数据压缩 与 数据查询 获取完整语法;
- 通过 参数绑定 与 Schemaless 写入 提升应用写入吞吐。
【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考