基本概念
表(Table)
为充分利用其数据的时序性和其他数据特点,TDengine 采取一个数据采集点一张表的策略,要求对每个数据采集点单独建表(比如有一千万个智能电表,就需创建一千万张表),用来存储这个数据采集点所采集的时序数据。
超级表(STable)
超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(TAG)是不一样的
子表(Subtable)
当为某个具体数据采集点创建表时,用户可以使用超级表的定义做模板,同时指定该具体采集点(表)的具体标签值(TAG)来创建该表。通过超级表创建的表称之为子表。
标签(Tag)
标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等,数据类型可以是任何类型。
TAG 是一个很特殊的数据列:
- 属于静态数据,创建后无需更新及插入。
- 同一张子表里每一行数据都应具有相同的 TAG 值。
- TAG 值在做
group by
或者partition by
的时候可以带来极高的性能。- 因为不同 TAG 组合的表在物理上存储在不同的连续地址上,相当于提前
group by
完成了,空间换时间。 - 比如
group by
配合last_row
的时候,如果是group by
的是 TAG 列,则可以直接去每张表中取最后一行,效率极高。 - 否则如果
group by
的是普通数据列,则需要遍历全表,性能非常差。
- 因为不同 TAG 组合的表在物理上存储在不同的连续地址上,相当于提前
一张子表里同一个 TAG 列的值是一样的,无法在一张子表某个 TAG 列里存入不同的值。所以通过超级表创建的子表的数量,应该等于超级表每个 TAG 列里值的数量的乘积。比如,假设超级表有 TAG_1
,TAG_2
两个 TAG 列,TAG_1
有 2
个值,TAG_2
有 3
个值,那么创建的子表数量就应该等于 2 * 3 = 6
张子表。不同的 TAG 值组合必须对应不同的子表,但是子表的名字本身跟 TAG 没有强关联性。
-- 先切换到指定database,否则show命令会报错(感觉像TDengine的bug)
use dispatcher_data;
-- 描述子表,可见有两个TAG列(type, enterprise_id)
describe tag_two_1;
-------------+---------+------+----+
field |type |length|note|
-------------+---------+------+----+
ts |TIMESTAMP| 8| |
timestr |VARCHAR | 12| |
count |INT | 4| |
type |INT | 4|TAG |
enterprise_id|VARCHAR | 32|TAG |
-------------+---------+------+----+
-- 查看子表的TAG详细信息
-- 可见TAG值(type, enterprise_id)已经作为meta信息存入了,实际上每张子表的TAG信息必须是一致且不可变的
-- 此时即使我设置不同的TAG值尝试插入,也只有普通数据插入成功,后来设置TAG的值实际上是未使用的
show tags from tag_two_1;
----------+---------------+------------------------+-------------+-----------+----------+
table_name|db_name |stable_name |tag_name |tag_type |tag_value |
----------+---------------+------------------------+-------------+-----------+----------+
tag_two_1 |dispatcher_data|t_realtime_count_tag_two|type |INT |1 |
tag_two_1 |dispatcher_data|t_realtime_count_tag_two|enterprise_id|VARCHAR(32)|1Kf5ZyXsPU|
----------+---------------+------------------------+-------------+-----------+----------+
-- 查看超级表,可见TAG值(type, enterprise_id)
select * from t_realtime_count_tag_two limit 1;
-----------------------+-------+-----+----+-------------+
ts |timestr|count|type|enterprise_id|
-----------------------+-------+-----+----+-------------+
2024-06-09 09:33:03.100| | 1| 1|1Kf5ZyXsPU |
-----------------------+-------+-----+----+-------------+
-- 查看子表信息,看不到TAG值(因为反正本表内TAG值一样,无需显示)
-- 只能看到普通数据的值
select * from tag_two_1 limit 1;
-----------------------+-------+-----+
ts |timestr|count|
-----------------------+-------+-----+
2024-06-09 09:33:03.100| | 1|
-----------------------+-------+-----+
基本操作
-- 创建数据库
CREATE DATABASE IF NOT EXISTS `dispatcher_data`
SINGLE_STABLE 0 -- 允许创建多张超级表
PRECISION 'us' -- 时间戳精度微秒
DURATION 1d
KEEP 7d
-- 其他的使用默认值
;
-- 查看数据库建表语句
SHOW CREATE DATABASE `dispatcher_data` \G;
-- 创建超级表
CREATE STABLE `dispatcher_data`.`t_top_info` (
ts TIMESTAMP,
`content` VARCHAR(2000)
) TAGS (
`type` INT
)
-- 插入数据(`USING`语法)
INSERT INTO `dispatcher_data`.`t_top_info_1` USING `dispatcher_data`.`t_top_info`
TAGS (1) VALUES (
now(),
'some content',
)
-- 插入数据(一般语法)
INSERT INTO `dispatcher_data`.`t_top_info` (
tbname, -- 子表名称,此项为必须
ts,
content,
type -- TAG
) VALUES (
't_top_info_1',
now(),
'some content',
1
)
Comments