ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TDengine Supertable 完整指南:从 CREATE STABLE 到 ALTER STABLE 的建模、查询与运维

TDengine Supertable 完整指南:从 CREATE STABLE 到 ALTER STABLE 的建模、查询与运维 TDengine Supertable 完整指南从 CREATE STABLE 到 ALTER STABLE 的建模、查询与运维【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengineTDengine 的超级表Supertable是一套将**表结构Schema与标签Tags**分离的数据建模机制同一类设备/采集点的共性测点定义为列Metric设备的静态属性定义为标签Tag通过一个超级表 大量子表Subtable的模式承载海量时序设备数据。本文以 Supertables 文档为骨架结合 TDengine 仓库中的语法解析器sql.y、元数据校验实现mndStb.c与自动化测试用例系统讲解超级表的创建、查看、删除、修改与查询并深入说明复合主键、表级 KEEP、虚拟超级表等进阶能力。读完本文你将能够独立完成超级表的全生命周期建模、按标签批量管理子表、并通过ALTER STABLE安全演进表结构。一、超级表是什么模型与核心概念在 TDengine 中一张超级表由以下三部分构成列Metric / 数据列描述采集数据本身的测点如电压、电流、温度所有子表共享同一组列定义时间戳主键每张表的第一列必须是TIMESTAMP系统自动将其设为主键标签Tag描述设备的静态维度信息如设备 ID、地理位置、厂商用于快速过滤与聚合。创建超级表后业务侧通过CREATE TABLE ... USING stb_name TAGS (...)以超级表为模板批量创建子表每张子表拥有完整列结构 一份独立的标签值。数据写入子表查询既可以按子表进行也可以在超级表上跨子表做投影与聚合详见 Tables 中的子表创建语法。从仓库源码看CREATE STABLE与CREATE TABLE在语法层面共用一套列定义解析但通过一个布尔标记区分在 sql.y 中CREATE TABLE ... tags_def_opt走createCreateTableStmt(pCxt, A, false, ...)而CREATE STABLE ... tags_def走createCreateTableStmt(pCxt, A, true, ...)——true即表示创建的是超级表。二、创建超级表CREATE STABLE2.1 完整语法CREATE STABLE [IF NOT EXISTS] [db_name.]stb_name (create_definition [, create_definition] ...) TAGS (create_definition [, create_definition] ...) [BASE ON [db_name.]parent_stb_name [, [db_name.]parent_stb_name] ...] [table_options] create_definition: col_name column_definition column_definition: type_name [COMPOSITE KEY] [ENCODE encode_type] [COMPRESS compress_type] [LEVEL level_type] table_options: table_option ... table_option: { COMMENT string_value | SMA(col_name [, col_name] ...) | KEEP value | VIRTUAL {0 | 1} }2.2 一个最小可用示例CREATE DATABASE power; USE power; CREATE STABLE meters ( ts TIMESTAMP, voltage FLOAT, current FLOAT ) TAGS ( location BINARY(20), group_id INT );以上语句创建一个用于智能电表场景的超级表meters随后即可批量创建子表CREATE TABLE d1001 USING meters TAGS (California.SanFrancisco, 2); CREATE TABLE d1002 USING meters TAGS (California.LosAngeles, 2);2.3 命名与基础约束超级表名、列名、标签名的命名规则与普通表一致详见 Naming Rules合法字符为英文字母、数字、下划线必须以字母或下划线开头大小写不敏感不能使用保留关键字如需更自由的命名可用反引号转义。超级表最多 4096 列含标签列虚拟超级表最多 32767 个数据列标签列仍以 128 个为上限。超级表至少包含 3 列一个时间戳列主键列、一个测点列、一个标签列。第一列必须是TIMESTAMP类型系统自动将其设为主键。上述限制在源码中有直接对应。在 tdef.h 中#define TSDB_MAX_COLUMNS 32767 // 虚拟表 / 虚拟超级表的最大列数 #define TSDB_MAX_COLUMNS_NON_VIRTUAL 4096 // 普通超级表的最大列数 #define TSDB_MIN_COLUMNS 2 // PRIMARY COLUMN(timestamp) other columns而 mndStb.c 的 mndCheckCreateStbReq 在创建请求校验时依次检查numOfColumns numOfTags不得超过上限、标签数必须 ≥1 且 ≤128、第一列必须是TSDB_DATA_TYPE_TIMESTAMP任何一项不满足都会返回对应的TSDB_CODE_*错误。这也解释了为什么至少三列中的两列下限来自TSDB_MIN_COLUMNS时间戳 1 测点再加至少 1 个标签。2.4 COMPOSITE KEY复合主键默认情况下时间戳是唯一主键。通过COMPOSITE KEY关键字可以为超级表指定第二主键列与时间戳共同构成复合主键CREATE STABLE sensor_data ( ts TIMESTAMP, device_id INT COMPOSITE KEY, value FLOAT ) TAGS (region VARCHAR(16));复合主键列的类型限制整数类型INT、BIGINT、INT UNSIGNED、BIGINT UNSIGNED字符串类型VARCHAR、BINARY。去重语义当超级表带有复合主键时只有当时间戳列和第二主键列同时相同两条记录才被视为重复记录此时数据库只保留最新的一条否则两条记录都会保留。2.5 ENCODE / COMPRESS / LEVEL列级编码与压缩ENCODE、COMPRESS、LEVEL三个选项用于在创建列时按列配置一级编码Encoding与二级压缩Compression算法完整算法矩阵与默认值见 Data Compression。核心要点一级压缩编码simple8b、bit-packing、delta-i、delta-d、bss字节流拆分、disabled二级压缩lz4、zlib、zstd、tsz、xz、disabled压缩级别high压缩率最高、速度最慢、low速度最快、压缩率最低、medium均衡默认支持缩写h/l/m。示例CREATE STABLE telemetry ( ts TIMESTAMP, temp FLOAT ENCODE bss COMPRESS zstd LEVEL high, counter BIGINT ENCODE delta-i COMPRESS lz4 ) TAGS (node_id INT);注意虚拟超级表VIRTUAL 1不支持ENCODE与COMPRESS。2.6 TAGS 子句标签列定义TAGS子句定义超级表的标签列有以下限制TIMESTAMP类型的标签列在插入时必须提供字面量时间戳值不支持NOW 10s这类算术表达式标签列名必须在所有列中唯一测点列与标签列不能同名标签列名不能使用保留关键字超级表最多 128 个标签列且至少 1 个标签列所有标签列的总长度不能超过 16 KB。这些限制同样能在 tdef.h 中找到常量定义#define TSDB_MAX_TAGS_LEN 16384 // 16 KB #define TSDB_MAX_TAGS 128并在 mndCheckCreateStbReq 中做了运行时校验。2.7 表级选项COMMENT / SMA / KEEP / VIRTUALCOMMENT表注释最大长度 1024 字节可用于超级表、子表与普通表详见 Tables。SMASmall Materialized Aggregates小物化聚合按数据块进行MAX/MIN/SUM的预计算以加速聚合查询。默认情况下系统会对大多数列自动创建块级 SMABINARY、NCHAR等类型不创建若在创建时显式指定SMA(col_name, ...)则只为列出的列创建块级 SMACREATE STABLE power ( ts TIMESTAMP, voltage FLOAT, current FLOAT, power FLOAT ) TAGS (loc VARCHAR(20)) SMA(voltage, current, power);KEEP数据保留期与 Databases 中的库级KEEP语义类似但存在三点重要差异超级表级KEEP必须小于数据库级KEEP超级表级KEEP不会立即生效——必须先对数据库执行FLUSH再执行COMPACT被超级表级KEEP标记为过期的数据才会被真正移除如果先 compact 数据库、再修改超级表级KEEP值、然后又 compact 一次过期数据可能无法被完全清除。仓库中的自动化测试 test_stable_keep_compact.py 完整覆盖了这一行为测试先创建带KEEP的数据库DURATION {duration}h KEEP {keep}再通过CREATE STABLE ... KEEP {keep_days}d创建表级 KEEP 的超级表插入 17 天前的历史数据后执行 FLUSH COMPACT 并验证过期数据是否被清除。测试中对KEEP与DURATION的约束keep 3*duration也印证了数据库创建时必须满足KEEP 至少为 DURATION 的 3 倍这一规则。VIRTUAL虚拟超级表VIRTUAL 1表示创建虚拟超级表。虚拟表是逻辑表本身不存储数据查询时按虚拟表定义从一张或多张物理表/既有虚拟表中按时间戳对齐读取列数据并即时生成结果集。虚拟超级表作为虚拟子表的模板有以下限制不支持COMPOSITE KEY不支持压缩选项ENCODE/COMPRESS可通过BASE ON子句从一个或多个父虚拟超级表继承列与标签详见 Virtual Supertable Inheritance。CREATE STABLE p_device (ts timestamp, status int) TAGS (region int) VIRTUAL 1; CREATE STABLE p_temp (ts timestamp, temp float) TAGS (sensor_id int) BASE ON test_db.p_device VIRTUAL 1;2.8 BASE ON虚拟超级表继承BASE ON子句用于虚拟超级表之间的继承子虚拟超级表VST继承父 VST 的所有标签以及除主时间戳外的所有列自身新增的列与标签追加在继承内容之后。约束包括BASE ON要求父子双方都必须是虚拟超级表VIRTUAL 1父子虚拟超级表必须位于同一个数据库子表自身的列/标签名不得与任何父表继承来的名称冲突循环继承会被检测并拒绝一个 VST 最多继承自10 个父 VST已有子节点的非叶子 VST 无法直接在其下创建虚拟子表也不能再作为BASE ON的目标父 VST 一旦成为非叶子节点其 Schema 即被冻结ADD COLUMN、DROP COLUMN、ADD TAG、DROP TAG、RENAME TAG及标签宽度修改都会被拒绝。三、查看超级表3.1 查看全部超级表SHOW [db_name.]STABLES [LIKE pattern];db_name缺省时显示当前数据库下的超级表LIKE支持模糊匹配。3.2 查看超级表创建语句SHOW CREATE STABLE [db_name.]stb_name;返回该超级表原始的创建 SQL常用于迁移或克隆已有超级表——在另一个集群中执行该语句即可得到结构完全一致的表。3.3 查看超级表结构DESCRIBE [db_name.]stb_name;展示列的字段名、类型与压缩设置。3.4 查看超级表下所有子表的标签SHOW TABLE TAGS [tag_name [, tag_name] ...] FROM table_name [FROM db_name]; -- 或 SHOW TABLE TAGS [tag_name [, tag_name] ...] FROM [db_name.]table_name;table_name既可以是子表展示该子表标签也可以是超级表名此时展示其下所有子表及其标签。实际输出示例taos SHOW TABLE TAGS FROM st1; tbname | id | loc | st1s1 | 1 | losangeles | st1s2 | 2 | sanfrancisco | st1s3 | 3 | sacramento | Query OK, 3 rows in database (0.004455s)也可以只查看指定标签列taos SELECT DISTINCT TBNAME, id FROM st1; tbname | id | st1s1 | 1 | st1s2 | 2 | st1s3 | 3 | Query OK, 3 rows in database (0.002891s)注意此语句必须包含DISTINCT与TBNAME才能保证在数据缺失或数据集很大时结果准确且执行快速。3.5 查看指定子表的标签taos SHOW TAGS FROM st1s1; table_name | db_name | stable_name | tag_name | tag_type | tag_value | st1s1 | test | st1 | id | INT | 1 | st1s1 | test | st1 | loc | VARCHAR(20) | sanfrancisco | Query OK, 2 rows in database (0.003684s)同样支持只查看指定标签taos SELECT DISTINCT TBNAME, id, loc FROM st1s1; tbname | id | loc | st1s1 | 1 | sanfrancisco | Query OK, 1 rows in database (0.001884s)从语法层面看SHOW TABLE TAGS与SHOW TAGS FROM在解析器 sql.y 中是两条独立的文法规则分别构造QUERY_NODE_SHOW_TAGS_STMT与createShowTableTagsStmt前者定位单张子表后者支持通过tag_list_opt指定标签列并在超级表范围聚合输出。四、删除超级表DROP STABLEDROP STABLE [IF EXISTS] [db_name.]stb_name;:::important 删除超级表会级联删除该超级表下创建的所有子表及其数据务必谨慎操作。 :::需要注意的是删除超级表不会立即释放磁盘空间。超级表会立刻被标记为待删除查询也不再返回该表的数据但磁盘空间要等到操作系统自动回收或用户手动COMPACT数据库后才会释放。这与 Tables 中普通表的删除语义一致。五、修改超级表ALTER STABLE5.1 完整语法ALTER STABLE [db_name.]stb_name alter_table_clause alter_table_clause: { alter_table_options | ADD COLUMN col_name column_type | DROP COLUMN col_name | MODIFY COLUMN col_name column_type | ADD TAG tag_name tag_type | DROP TAG tag_name | MODIFY TAG tag_name tag_type | RENAME TAG old_tag_name new_tag_name | ADD BASE ON [db_name.]parent_stb_name [, [db_name.]parent_stb_name] ... | DROP BASE ON [db_name.]parent_stb_name [, [db_name.]parent_stb_name] ... } alter_table_options: alter_table_option ... alter_table_option: { COMMENT string_value | KEEP value }关键语义修改超级表的 Schema 会影响其下所有子表任何子表都不能单独修改自身 Schema仅SET TAG更新标签值除外。标签定义同样只能在超级表级别修改并作用于该超级表下的全部子表。禁止事项不能对超级表的主键列执行增、删、改操作不能ADD COLUMN/DROP COLUMN/MODIFY COLUMN主键列。各操作说明操作说明ADD COLUMN为超级表增加一个测点列DROP COLUMN删除一个测点列同时从所有子表中删除该列MODIFY COLUMN仅可加长BINARY、VARCHAR、NCHAR等变长类型测点列的长度其他类型不可修改长度不可缩短ADD TAG增加一个标签列总数 ≤128总长度 ≤16 KBDROP TAG删除一个标签列同时从所有子表中删除该标签MODIFY TAG仅可加长BINARY、VARCHAR、NCHAR等变长类型标签列的长度其他类型不可修改长度不可缩短RENAME TAG重命名标签列作用于所有子表ADD BASE ON/DROP BASE ON修改虚拟超级表的继承关系详见 Alter Inheritance在解析器 sql.y 中可以看到ALTER STABLE alter_table_clause与ALTER TABLE共用同一套alter_table_clause文法仅通过setAlterSuperTableType标记为超级表操作ADD BASE ON/DROP BASE ON则对应createAlterTableBaseOn这是超级表确切说是虚拟超级表独有的修改能力。5.2 增加测点列ALTER STABLE stb_name ADD COLUMN col_name column_type;5.3 删除测点列ALTER STABLE stb_name DROP COLUMN col_name;5.4 修改测点列长度ALTER STABLE stb_name MODIFY COLUMN col_name data_type(length);目标列必须是BINARY、VARCHAR或NCHAR等变长类型新长度必须大于现有长度不允许缩短。5.5 增加标签列ALTER STABLE stb_name ADD TAG tag_name tag_type;注意增加后标签总数不能超过 128所有标签总长度不能超过 16 KB。当向超级表新增标签列时其下所有子表会自动继承新标签新标签的默认值为NULL。5.6 删除标签列ALTER STABLE stb_name DROP TAG tag_name;5.7 重命名标签列ALTER STABLE stb_name RENAME TAG old_tag_name new_tag_name;5.8 修改标签列长度ALTER STABLE stb_name MODIFY TAG tag_name data_type(length);目标标签必须是BINARY、VARCHAR或NCHAR等变长类型新长度必须大于现有长度不允许缩短。仓库测试 test_stable_alter_basic.py 覆盖了上述列/标签增删改的基础路径可作为自行验证时的参照。六、查询超级表超级表支持使用SELECT进行投影与聚合查询并可在WHERE子句中同时对测点列与标签列进行过滤。例如SELECT COUNT(*), AVG(voltage) FROM meters WHERE group_id 2 AND ts NOW - 1h;结果排序说明如果超级表查询不包含ORDER BY返回结果会按子表分组——先返回某个子表的全部记录再返回下一个子表的全部记录即返回数据整体不保证有序。如需严格排序必须显式添加ORDER BYSELECT * FROM meters WHERE ts NOW - 1h ORDER BY ts;:::note 除更新标签值外所有标签操作都只能在超级表上进行不能对某个子表单独增加、删除或修改标签列。 :::七、实战建议与注意事项建模先行把随设备变化的测点放列Column把相对静态的维度放标签Tag标签数尽量控制在 128 以内、总长度 16 KB 以内超级表总列数含标签不要超过 4096。利用复合主键当同一时间戳下同一设备可能出现多条不同来源记录时用COMPOSITE KEY声明第二主键获得时间戳 来源维度的去重语义。按需压缩整数/浮点列可组合ENCODE与COMPRESS降低存储成本BINARY/NCHAR默认二级压缩为zstd无需额外配置即可获得较好压缩率。KEEP 的生效时机表级KEEP不会即时生效必须FLUSHCOMPACT后才清除过期数据且反复 compact 改 KEEP 可能导致过期数据残留生产环境应避免频繁调整。Schema 演进而非重建需要新增测点/标签时优先使用ALTER STABLE ADD COLUMN / ADD TAG一次性作用于全部子表删除列/标签前确认该操作会级联到所有子表。迁移复用用SHOW CREATE STABLE导出的建表语句可直接在目标集群重放保证结构完全一致。八、总结超级表是 TDengine 面向工业物联网IIoT场景的核心建模设施。本文以 Supertables 为主线完整覆盖了CREATE STABLE含复合主键、标签约束、SMA、KEEP、VIRTUAL、BASE ON、SHOW/DESCRIBE系列查看命令、DROP STABLE的级联语义与空间释放机制、ALTER STABLE的列/标签/继承关系全量修改能力以及超级表查询的排序行为。每一处关键限制都能在仓库源码中找到对应实现列数上限定义在 tdef.h标签上限定义在 tdef.h创建校验逻辑位于 mndStb.c 的 mndCheckCreateStbReq语法规则位于 sql.y。结合仓库中的测试用例test_stable_keep_compact.py、test_stable_alter_basic.py读者可以在本地环境直接复现并验证上述全部行为。【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进