网站app的意义,担保公司发展规划,中金超钒 网站建设,苏州优化有限公司1. 简介
从 TDengine 3.3.0.0 版本之后#xff0c;新增了复合主键的功能。
TDengine 原来的时间列是不允许有重复时间戳的#xff0c;有了复合主键功能后#xff0c;时间列即允许有重复#xff0c;重复后的时间戳按紧跟其后第二列主键列的值来确定唯一性。
此功能的常用…1. 简介
从 TDengine 3.3.0.0 版本之后新增了复合主键的功能。
TDengine 原来的时间列是不允许有重复时间戳的有了复合主键功能后时间列即允许有重复重复后的时间戳按紧跟其后第二列主键列的值来确定唯一性。
此功能的常用场景如高速收费口同一时间内可能会多辆车通过股票交易记录同一时间内笔成交等多种实际应用场景。
2. 功能说明
2.1 建表
用户可以在建表时用 PRIMARY KEY 关键字额外指定除主键时间戳列以外的另一列作为主键列该列与时间戳列共同组成一行数据的键值其类型必须为整型int32, int64, uint32, uint64) 或 字符串类型varchar。超级表与普通表均支持复合主键。复合主键列不支持修改、增加和删除操作。PRIMARY KEY 列只能设置为第二列。
具体 SQL 语句如下 CREATE TABLE t ( ts TIMESTAMP, obj_id VARCHAR(64) PRIMARY KEY, data1 FLOAT, data2 int ); 2.2 写入
只有当时间戳相同且 PRIAMRY KEY 列值都相同时两行数据才会被认为是重复数据否则被认为是两行不同数据。如果时间戳相同但 Primary key 较小数据后写入则视为乱序数据处理。
schemaless 写入不支持复合主键的情况因为 schemaless 本身就是没有 schema没法确定复合主键目前的三种 schemaless 协议 influxdb line/opentsdb telnet/opentsdb json) 也没有复合主键这个概念。
2.3 删除
删除操作与现有删除操作一样只支持按时间段删除不支持按主键范围删除。
2.4 查询
2.4.1 数据读取
查询复合主键数据时时间戳相同且 PRIMARY KEY 列值相同时被认为是一行数据。对于复合主键时间戳PRIMARY KEY 列相同但被多次写入的重复数据则在合并更新后返回。只有复合主键不同的行被认为不同的行数据被查询分别返回。每个表的读取结果是按时间戳主键Primary Key有序。其他查询行为也将相应地变动。具体变化内容见后续章节。
查询行为的适配源自于TSDB reader 返回给上层的基础数据结构 SSDataBlock中包含了时间戳相同但primary key 不同的记录。
2.4.2 标量查询
此原来行为相同无改变
2.4.3 聚合查询
非时间窗口类用户可见层面无变化。时间窗口聚合类TDengine 系统中针对时间窗口采用闭区间进行描述并且相同时间戳不同primary key的记录归属于同一个时间窗口。故用户可见的时间窗口无变化。在超级表的查询中已经有归属于不同时间线的相同时间戳的查询增加了 primary key 以后用户可见表现层面无任何变化。
2.4.4 查询函数 类别函数名是否变化数据函数ABS无影响ACOS无影响ASIN无影响ATAN无影响CEIL无影响COS无影响FLOOR无影响LOG无影响POW无影响ROUND无影响SIN无影响SQRT无影响TAN无影响字符串函数CHAR_LENGTH无影响CONCAT无影响CONCAT_WS无影响LENGTH无影响LOWER无影响LTRIM无影响RTRIM无影响SUBSTR无影响UPPER无影响时间和日期函数TIMEDIFF无影响TIMETRUNCATE无影响转换函数CAST无影响TO_ISO8601无影响TO_JSON无影响TO_UNIXTIMESTAMP无影响TO_CHAR无影响TO_TIMESTAMP无影响聚合函数APERCENTILE无影响AVG无影响COUNT无影响ELAPSED无影响LEASTSQUARES无影响SPREAD无影响STDDEV无影响SUM无影响HYPERLOGLOG无影响HISTOGRAM无影响PERCENTILE无影响选择函数BOTTOM无影响FIRST有变化INTERP有变化LAST有变化LAST_ROW有变化MAX无影响MIN无影响MODE无影响SAMPLE无影响TAIL无影响TOP无影响UNIQUE有变化时序数据特有函数CSUM无影响DERIVATIVE有变化DIFF有变化IRATE有变化MAVG无影响STATECOUNT无影响STATEDURATION无影响TWA有变化
变化的函数行为变化如下
1. Interp
Interp 函数返回设定时间点 T 0 的插值断面数据其前置时间戳 Tprev小于 T0的最大时间戳或后置时间戳Tnxt大于T0的最小时间戳可能有重复时间并且其对应的数值不同。
进行插值计算时前置时间戳 Tprev 或后置时间戳 Tnxt 均只使用首次出现的记录进行计算丢弃其后出现的相同时间戳不同主键的记录。
首次出现的定义对于任一时间戳Tx在按照升序返回的数据记录中同一个表中数据第一条 Tx 的记录即为首次出现记录。降序返回的数据记录中同一个表中数据Tx 最后一次出现的记录为首次出现。
需要注意首次出现的判定只针对同一个表对于超级表下的不同的表无首次出现的判定。
2. FIRST
First 返回时间戳最小的记录。对于同一个表中具有相同最小时间戳不同主键的情况返回该表中具有该时间戳的所有记录中首次出现的记录。
首次出现定义同上。
超级表查询中在完成上述逻辑以后还需要对来自不同表的时间戳进行比较和取舍针对来自不同vnode的记录如果 ts 相同需要进行 primary key 的比较。因此 first 函数返回的全局最小的ts primary key 最早的结果。
3. LAST
Last 返回时间戳最大的记录。对于同一个表中具有相同最大时间戳不同主键的情况返回该表中具有该时间戳的所有记录中末次出现的记录。
末次出现定义对应于首次出现的定义。
针对超级表跨 vnode 查询返回的结果其判定逻辑于 FIRST 函数处理逻辑相同需要同时比较 ts primary key
4. LAST_ROW
与 last 函数相同。
5. UNIQUE
Unique 返回任一时间戳第一次出现的记录。对于同一个表中的记录只返回首次出现的记录。不同子表中的相同时间戳记录判定逻辑不变。
首次出现定义同上。
6. DERIVATIVE
同一个子表中的记录使用首次出现记录进行计算忽略后续出现的相同时间戳不同主键的记录。
首次出现定义同上。
7. DIFF
同一个子表中的记录使用首次出现记录进行计算忽略后续出现的相同时间戳不同主键的记录。
首次出现定义同上。
8. IRATE
同 derivative 函数处理逻辑相同。
9. TWA
同一个子表中数据进行窗口边界插值的时候均使用首次出现记录进行插值计算返回结果。非首次出现记录不参与计算。
首次出现定义同上。 10. show create
Show create 返回创建超级表的SQL 语句对于有 primary key 的超级表相应的 SQL 语句有变化
11. DESC table_name
DESC 获取 超级表的 schema 信息返回的结果中需要标记第二列primary key 只能为第二列是否是 primary key 列。
12. INSERT INTO table_name SELECT
会进行符合性检查具有 primary key 的超级表的不能向无 primary key 的表中写入数据。无 primary key 的表可以向具有 primary key 的表写入数据。
向 primary key 的表写入数据的时候要求 primary key 列必须非 NULL。
2.4.5 查询子句 序号 子句 行为变化 1 比较表达式/条件子句 无影响 2 fill 子句 无影响 3 窗口子句 无影响 4 group by 子句 无影响 5 partition by 子句 无影响 6 join 查询 无影响 7 Distinct 子句 无影响 8 union子句 无影响 9 slimit子句 无影响 10 limit子句 无影响 11 order by子句 无影响 12 having子句 无影响 13 range子句 无影响 14 every子句 无影响 15 子查询 无影响
2.5 流计算
2.5.1 流计算窗口
对我们所支持的窗口类型即 Interval、Session窗口如果数据源表是复合主键数据先按时间戳排序时间戳相同的再按复合主键排序然后才是其他列排序。所以复合主键场景流计算当前的设计和实现能够透明处理符合流计算窗口当前的预期。存储流计算结果的表是复合主键则Interval、Session 窗口输出结果时需要按照时间戳和复合主键排序。
流计算对于乱序数据的界定方式当前这批写入的数据与之前写入的数据做对比。窗口计算要求数据按时间戳有序只是要求当前这批数据这个是局部的并不是要求数据源的全部数据有序。
2.5.2 创建流计算
需要考虑存储流计算结果的表。对于自动创建超级表场景需要提供复合主键的信息。新增语法在创建流计算的SQL中显式指定复合主键信息即流计算结果中哪些列是复合主键。对于写入已存在超级表通过元数据能够获取复合主键的信息不需要SQL中指定。
语法如下 CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name[(field1_name, field2_name [PRIMARY KEY], field3_name, ...)] [TAGS (create_definition [, create_definition] ...)] SUBTABLE(expression) AS subquery PRIMARY KEY 使用规则和限制与建表SQL相同。
2.5.3 流计算中不支持的场景
由于需要按照 PK 删除 已经生成的记录。因此不支持状态窗口、事件窗口、计数窗口在有 pk 的表上进行计算。对于全是标量函数的流计算不支持数据源是复合主键且目标表不是复合主键。 2.6 订阅
2.6.1 接口变更 tmq_get_json_meta获取meta信息的 json 描述 该接口内部创建表数据结构里增加列是否是复合主键参数isPrimarykey:true。已在文档里更新 https://jira.taosdata.com:18090/pages/viewpage.action?pageId158206215 tmq_get_raw 接口返回的 raw data 做了升级请查看文档 数据订阅结果序列化方案
2.6.2 其它接口无变更
2.7 Last 缓存 cache_model: none返回最大的时间戳和该时间戳下最大的主键所对应的行或值 cache_mode: last_value, last_row, both查询行为受缓存更新规则影响更新规则如下 缓存的更新粒度仍然是表级别。在主时间戳列相同情况下主键列按大小顺序取最大值。即在更新缓存时新到达的数据与当前 last 缓存中的数据相比如果时间戳更大或时间戳相同但主键值更大则更新缓存否则不更新缓存。
3. 性能影响
3.1 写入性能 非重复时间戳在没有任何两条记录时间戳相同的情况下其写入性能与未引入 primary key 相比完全相同 有重复时间戳的场景在极端情况下时间戳全部相同而 primary key 单调递增预估这种场景下写入性能下降 50%原因是要进行两次键值比较。 纯乱序数据写入即任意一行记录的时间戳和 primary key 都有可能小于之前已经写入的部分记录这种情况下仍旧无法预估性能下降的比例。原则乱序程度越高性能下降越明显
3.2 查询性能
3.2.1 数据读取
读取过程中在merge阶段需要同时比较 ts 和 primary key column因此 merge 过程会消耗更多的 CPU记录合并过程会出现明显地性能下降。
合并过程是在 tsdb 完成因此所有的查询均受影响只使用 head 文件 和 SMA 索引的查询除外。性能受到的影响程度受 key长度、数据写入模式、数据在文件中物理分布、数据重复比例、数据读取开销在整个查询过程中资源开销占比等诸多因素共同影响无法简单评估性能下降的程度。
3.2.2 不同类型查询性能表现
在排除数据读取性能降低的场景下对于非分组类型的查询没有 partition by 和 group by 子句没有明显的变化。
4. 兼容性
1. 不会对已存在的数据产生影响数据不支持版本回退因为低版本识别不出复合主键。
2. 流计算会有影响。需要删除删除流计算才能进行升级。
5. 约束和限制 只允许额外指定除时间戳以外的一列作为主键 支持定长和变长类数据类型暂定支持非浮点数及 varchar。 主键与时间戳列一样不允许缺省或为 NULL 主键列不允许 alter 或 drop 等操作 已建无主键列的表不可以通过 alter 语句添加主键列 不支持对主键列的范围删除
6. 总结
本章主要介绍了新功能复合主键的对外接口使用、影响的功能及函数内部技术实现受约条件等帮助技术开发人员更好了解及使用此功能。