听说你还没有真正理解 TDengine 的超级表 STable

了解 TDengine 的朋友应该都知道,TDengine 要求每个数据采集点单独建表,这样能极大提高数据的插入/查询性能,但是导致系统中表的数量猛增,让应用对表的维护以及聚合、统计操作难度加大。因此,为降低应用的开发难度,TDengine 引入了超级表 STable (Super Table)的概念。
那么到底什么是「超级表」?

超级表定义

STable 是同一类型数据采集点的抽象,是同类型采集实例的集合。每个 STable 包含多张数据结构一样的子表,并为其子表定义了表结构和一组标签:
表结构即表中记录的数据列及其数据类型;
标签名和数据类型由 STable 定义,标签值记录着每个子表的静态信息,用于对子表进行分组过滤。

子表本质上就是普通的表,由一个时间戳主键和若干个数据列组成,每行记录着具体的数据,数据查询操作与普通表完全相同;但子表与普通表的区别在于每个子表从属于一张超级表,并带有一组由 STable 定义的标签值。
每种类型的采集设备可以定义一个 STable。数据模型定义表每列数据的类型,如温度、压力、电压、电流、GPS 实时位置等;而标签信息属于 Meta Data,如采集设备的序列号、型号、位置等,它是静态的,是表的元数据。用户在创建表(数据采集点)时除可以指定 STable(采集类型)外,还可以指定标签的值。
TDengine 扩展标准 SQL 语法用于定义 STable,使用关键词 tags 指定标签信息。语法如下:

CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,…)   TAGS(tag_name tag_type, …) 

其中 tag_name 是标签名,tag_type 是标签的数据类型。标签可以使用时间戳之外的其他 TDengine 支持的数据类型,标签的个数最多为 6 个,名字不能与系统关键词相同,也不能与其他列名相同。如:

create table thermometer (ts timestamp, degree float) tags (location binary(20), type int)

上述 SQL 创建了一个名为 thermometer 的 STable,带有标签 location 和标签 type。
为某个采集点创建表时,可以指定其所属的 STable 以及标签的值,语法如下:

CREATE TABLE <tb_name> USING <stb_name> TAGS (tag_value1,...)

沿用上面温度计的例子,使用超级表 thermometer 建立单个温度计数据表的语句如下:

create table t1 using thermometer tags (‘beijing', 10)

上述 SQL 以 thermometer 为模板,创建了名为 t1 的表,这张表的 Schema 就是 thermometer 的 Schema,但标签 location 值为 ‘beijing’,标签 type 值为 10。
用户可以使用一个 STable 创建数量无上限的具有不同标签的表,从这个意义上理解,STable 就是若干具有相同数据模型,不同标签的表的集合。与普通表一样,用户可以创建、删除、查看超级表 STable,大部分适用于普通表的查询操作都可运用到 STable 上,包括各种聚合和投影选择函数。除此之外,可以设置标签的过滤条件,仅对 STbale 中部分表进行聚合查询,大大简化应用的开发。
TDengine 对表的主键(时间戳)建立索引,暂时不提供针对数据模型中其他采集量(比如温度、压力值)的索引。每个数据采集点会采集若干数据记录,但每个采集点的标签仅仅是一条记录,因此数据标签在存储上没有冗余,且整体数据规模有限。TDengine 将标签数据与采集的动态数据完全分离存储,而且针对 STable 的标签建立了高性能内存索引结构,为标签提供全方位的快速操作支持。用户可按照需求对其进行增删改查(Create,Retrieve,Update,Delete,CRUD)操作。
STable 从属于库,一个 STable 只属于一个库,但一个库可以有一到多个 STable,一个STable 可有多个子表。

超级表管理

创建超级表

CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,…) TAGS(tag_name tag_type, …)

与创建表的 SQL 语法相似。但需指定 TAGS 字段的名称和类型。
说明:
TAGS 列总长度不能超过 512 bytes;

TAGS 列的数据类型不能是 timestamp 和 nchar 类型;

TAGS 列名不能与其他列名相同;

TAGS 列名不能为预留关键字。

显示已创建的超级表

写数据时自动建子表

在某些特殊场景中,用户在写数据时并不确定某个设备的表是否存在,此时可使用自动建表语法来实现写入数据时里用超级表定义的表结构自动创建不存在的子表,若该表已存在则不会建立新表。注意:自动建表语句只能自动建立子表而不能建立超级表,这就要求超级表已经被事先定义好。
自动建表语法跟 insert/import 语法非常相似,唯一区别是语句中增加了超级表和标签信息。具体语法如下:

INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ...;

向表tb_name中插入一条或多条记录,如果tb_name这张表不存在,则会用超级表stb_name定义的表结构以及用户指定的标签值(即tag1_value…)来创建名为tb_name新表,并将用户指定的值写入表中。如果tb_name已经存在,则建表过程会被忽略,系统也不会检查tb_name的标签是否与用户指定的标签值一致,也即不会更新已存在表的标签。

INSERT INTO <tb1_name> USING <stb1_name> TAGS (<tag1_value1>, ...) VALUES (<field1_value1>, ...) (<field1_value2>, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;

向多张表tb1_name,tb2_name等插入一条或多条记录,并分别指定各自的超级表进行自动建表。

STable 使用示例

以温度传感器采集时序数据作为例,示范 STable 的使用。在这个例子中,对每个温度计都会建立一张表,表名为温度计的 ID,温度计读数的时刻记为 ts,采集的值记为 degree。通过 tags 给每个采集器打上不同的标签,其中记录温度计的地区和类型,以方便我们后面的查询。所有温度计的采集量都一样,因此我们用 STable 来定义表结构。
定义 STable 表结构并使用它创建子表
创建 STable 语句如下:

CREATE TABLE thermometer (ts timestamp, degree double) TAGS(location binary(20), type int)

假设有北京,天津和上海三个地区的采集器共 4 个,温度采集器有 3 种类型,我们就可以对每个采集器建表如下:

CREATE TABLE therm1 USING thermometer TAGS ('beijing', 1);
CREATE TABLE therm2 USING thermometer TAGS ('beijing', 2);
CREATE TABLE therm3 USING thermometer TAGS ('tianjin', 1);
CREATE TABLE therm4 USING thermometer TAGS ('shanghai', 3);

其中 therm1,therm2,therm3,therm4 是超级表 thermometer 四个具体的子表,也即普通的 Table。以 therm1 为例,它表示采集器 therm1 的数据,表结构完全由 thermometer 定义,标签 location=”beijing”, type=1 表示 therm1 的地区是北京,类型是第 1 类的温度计。
写入数据
注意,写入数据时不能直接对 STable 操作,而是要对每张子表进行操作。我们分别向四张表therm1,therm2, therm3, therm4写入一条数据,写入语句如下:

INSERT INTO therm1 VALUES ('2018-01-01 00:00:00.000', 20);
INSERT INTO therm2 VALUES ('2018-01-01 00:00:00.000', 21);
INSERT INTO therm3 VALUES ('2018-01-01 00:00:00.000', 24);
INSERT INTO therm4 VALUES ('2018-01-01 00:00:00.000', 23);

按标签聚合查询
查询位于北京(beijing)和天津(tianjing)两个地区的温度传感器采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)、最低温度min(degree),并将结果按所处地域(location)和传感器类型(type)进行聚合。

SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree) FROM thermometer WHERE location='beijing' or location='tianjin' GROUP BY location, type 

按时间周期聚合查询
查询仅位于北京以外地区的温度传感器最近24小时(24h)采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)和最低温度min(degree),将采集结果按照10分钟为周期进行聚合,并将结果按所处地域(location)和传感器类型(type)再次进行聚合。

SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree) FROM thermometer WHERE name<>'beijing' and ts>=now-1d INTERVAL(10M) GROUP BY location, type

听说你还没有真正理解 TDengine 的超级表 STable

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值