基本概念

表(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_1TAG_2 两个 TAG 列,TAG_12 个值,TAG_23 个值,那么创建的子表数量就应该等于 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
Write a Comment