一、入门阶段:了解 TDengine 基础
1. TDengine 基本认知
- TDengine 是什么?
- TDengine是一款为物联网设计的时序数据库(时序数据指按照时间发生前后的顺序进行排列的序列数据。这种数据一般都是周期性产生或者事件触发,进行实时数据处理,例如电表异常监控。它的主要特点就是数据量大,实时的以周期为单位分析数据,一个数据采集点就是一个数据流等。具体可以参考官方文档:https://docs.taosdata.com/concept/)
- TDengine 与 MySQL的区别是什么?
-
服务于不同业务,TDengine适用于物联网存储机器生成的数据,Mysql是通用关系型数据库适用面更加广泛
-
表结构的定义不同
- Mysql以单表形式存储数据,通过字段的形式链接表与表之间的关系
- TDengine
- 定义超级表,超级表为模板不存储实际数据;子表使用超级表结构存储实际数据;查询时可以查询超级表,通过TAG去区分到那个子表中查询数据。(例子:超级表是一个电表,定义了多个数据采集点;子表是指具体的电表设备,通过TAG去区分是那个电表,TAG可以是电表型号/电表所在区域,所有电表的数据采集点都是一样的,复用超级表的即可)
- TD的第一列都为时间戳,而且是必须有的列。在时序数据库中任何没有时间的数据都没有意义。
-
Mysql支持join连表查询,TDengine不支持join不同的超级表,但是支持窗口([窗口概念](#2. 查询与聚合分析))
-
2. 核心概念
- 什么是 Super Table(超级表)?
- TD数据库里面超级表相当于一个模板,其中的子表需要跟超级表的结构一样,只是TAG可以不同。超级表是用于管理多个结构一样的数据采集点。
- 什么是 Sub Table(子表)?
- 通过超级表创建出来的子表拥有跟超级表一样的结构,属于超级表的具体实现。值得注意的是修改子表结构,超级表下面所有的子表结构都会改变。
- 什么是 Tag(标签)?它与 Field(字段)有何区别?
- 标签只的是传感器、设备或者其他采集点的静态属性。例如一个电表的型号,颜色,所在地等静态属性。 字段指的是采集量,例如电表中记录的电压、温度等数据。其中TAG是用来区分该数据采集点是哪个设备的,而Field是用来记录该设备下的采集量。
✅ 练习
- 在 TD 环境中建一个简单的表,插入几千行数据,执行基本查询。
二、应用阶段:时序数据建模与分析
1. 基础语法
-
DDL
-
创建超级表。第一列必须是时间戳。必须定义TAGS,可以定义多个。超级表里面没有储存数据
sqlCREATE STABLE meters ( ts timestamp, current float, voltage int, phase float ) TAGS ( location varchar(64), group_id int );
-
创建子表。创建子表时,需要 添加USING+超级表名,并且定义具体TAGS值
sqlCREATE TABLE d1001 USING meters ( location, group_id ) TAGS ( "California.SanFrancisco", 2 );
-
自动建表。使用insert语句时,如果没有子表自动创建子表。即在insert时,使用 USING+超级表名
sqlINSERT INTO d1002 USING meters TAGS ( "California.SanFrancisco", 2 ) VALUES ( NOW, 10.2, 219, 0.32 );
-
-
DML
- 跟常规SQL相近,多了一个窗口查询。[窗口查询](#2. 查询与聚合分析)
2. 查询与聚合分析
TD数据库是不支持多超级表join,他的join只局限于一个超级表中的子表使用,用于聚合多个子表当中的数据。建议直接使用union,把多个子表的查询数据合并到一起。
-
TDengine 支持哪些时间窗口函数?
-
固定窗口、滑动窗口。任何窗口都需要使用PARTITION BY进行数据分区(等效于group by)。系统内置字段:_wstar 统计窗口开始时间 _wend 统计窗口结束时间
-
固定窗口 使用 INTERVAL 关键字,如果设置INTERVAL(1h) 就表示聚合1h的数据。INTERVAL(时间窗口大小,偏移量) 偏移量指的是如果开始时间为1点,偏移量为1h时,那么就从两点开始生成时间窗口
sql//表示根据tbname分组,生成一小时内的 avg(voltage) 数据,当1h时内没有数据就不会生产固定窗口 SELECT tbname, _wstart, avg(voltage) FROM meters WHERE ts >= "2022-01-01T00:00:00+08:00" AND ts < "2022-01-01T00:05:00+08:00" PARTITION BY tbname INTERVAL(1h)
-
滑动窗口 使用INTERVAL 与SLIDING关键字。 当INTERVAL(1h) SLIDING(1h)即时间单位一致,那么这就属于固定窗口。
sql//每半个小时生成过去一小时的数据 也就是0点 聚合了0-1点的数据 0点30分 聚合了0:30-1:30的数据,一直往下 SELECT tbname, _wstart, _wend, avg(voltage) FROM meters WHERE ts >= "2022-01-01T00:00:00+08:00" AND ts < "2022-01-01T00:05:00+08:00" PARTITION BY tbname INTERVAL(1h) SLIDING(30m)
-
-
-
如何使用聚合查询、标签过滤、时间过滤?
-
TDengine 常用的聚合函数有哪些?
-
DIFF: 计算当前列与上一列的差值,第一列为null。不能用于分组,滑动窗口下。不能用于有重复时间戳的表中。
-
IRATE:计算时间窗口之间的瞬时增长率,即计算单位时间增长多少。举例
time | exhaust_temp | rate_per_sec ---------------------|--------------|------------- 10:00:00 | 100℃ | NULL -- 无前置数据 10:00:02 | 106℃ | 3℃/s -- (106-100)/(2-0)=3 10:00:05 | 112℃ | 2℃/s -- (112-106)/(5-2)=2
-
PERCENTILE(column, p):计算分位数。举例:PERCENTILE(温度, 50) 得到的结果是 温度的中间值。PERCENTILE(温度, 90) 表示有90%的数小于该值,10%的数大于该值,即 温度有 1 2 3 4 5 6 7 8 9 10 那么这个函数的结果是 9
-
3. 数据生命周期与多表分析
- 如何进行多表查询?
- 直接查询超级表中的数据就可以实现多表聚合查询(TD中多表查询指的都是在同一个超级表进行的操作)。
- 如何查询所有子表的数据?
- 同一个超级表内可以使用join,也可以使用union合并多个超级表下子表的查询结果集
✅ 练习
- 设计一个温湿度监控系统的超级表模型,并写 SQL 分析过去一周的平均温度变化。
三、实战与 Java 集成
1. Java 连接与写入(项目实战版)
-
如何在 Java 中使用DML语句管理TD数据
-
项目中引入TD的数据库驱动、JDBC自动加载器、Mybatis依赖
xml<!--TD的数据库驱动--> <dependency> <groupId>com.taosdata.jdbc</groupId> <artifactId>taos-jdbcdriver</artifactId> <version>3.7.5</version> </dependency> <!--动态数据源(包含JDBC自动加载器)--> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>${dynamic-ds.version}</version> </dependency> <!-- MyBatis 整合 Spring Boot 的 starter(核心依赖) --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency>
-
编写配置文件(Nacos/多数据中心为例子)
ymldatasource: dynamic: #连接池 hikari: connection-timeout: 10000 idle-timeout: 30000 max-lifetime: 900000 maximum-pool-size: 30 minimum-idle: 10 validation-timeout: 1000 datasource: # 主库数据源 master: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/alphacloud_alphaess?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8 username: root password: root td_alphacloud_alphaess: url: jdbc:TAOS-RS://127.0.0.1:6041/alphacloud_alphaess?timezone=UTC&batchfetch=true&charset=UTF-8 username: root password: taosdata driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
-
Mysql与TD,都跟Mybatis一致。同样的方法写sql,新建实体类,写mapper接口,写mapper.xml。区别只有sql语法有一点不同
-
2. 查询与数据处理
- 如何在 Java 层实现窗口聚合或实时分析?
- 正常使用mapper.xml写窗口聚合sql
✅ 练习
- 使用 Java 编写一个实时温度监控系统,定时写入与查询 TDengine 数据。