Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
loser646
TDengine
提交
7f8008a1
T
TDengine
项目概览
loser646
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
7f8008a1
编写于
9月 13, 2021
作者:
E
Elias Soong
提交者:
GitHub
9月 13, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #7901 from taosdata/docs/Update-Latest-Feature
Docs/update latest feature
上级
f449f250
358b876e
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
145 addition
and
6 deletion
+145
-6
documentation20/cn/00.index/docs.md
documentation20/cn/00.index/docs.md
+5
-3
documentation20/cn/05.insert/docs.md
documentation20/cn/05.insert/docs.md
+3
-2
documentation20/cn/08.connector/docs.md
documentation20/cn/08.connector/docs.md
+1
-1
documentation20/cn/12.taos-sql/02.udf/docs.md
documentation20/cn/12.taos-sql/02.udf/docs.md
+136
-0
未找到文件。
documentation20/cn/00.index/docs.md
浏览文件 @
7f8008a1
...
...
@@ -44,13 +44,15 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
*
[
SQL函数
](
/taos-sql#functions
)
:支持各种聚合函数、选择函数、计算函数,如avg, min, diff等
*
[
窗口切分聚合
](
/taos-sql#aggregation
)
:将表中数据按照时间段等方式进行切割后聚合,降维处理
*
[
边界限制
](
/taos-sql#limitation
)
:库、表、SQL等边界限制条件
*
[
UDF
](
/taos-sql/udf
)
:用户定义函数的创建和管理方法
*
[
错误码
](
/taos-sql/error-code
)
:TDengine 2.0 错误码以及对应的十进制码
## [高效写入数据](/insert)
*
[
SQL写入
](
/insert#sql
)
:使用SQL insert命令向一张或多张表写入单条或多条记录
*
[
Prometheus写入
](
/insert#prometheus
)
:配置Prometheus, 不用任何代码,将数据直接写入
*
[
Telegraf写入
](
/insert#telegraf
)
:配置Telegraf, 不用任何代码,将采集数据直接写入
*
[
SQL 写入
](
/insert#sql
)
:使用SQL insert命令向一张或多张表写入单条或多条记录
*
[
Schemaless 写入
](
/insert#schemaless
)
:免于预先建表,将数据直接写入时自动维护元数据结构
*
[
Prometheus 写入
](
/insert#prometheus
)
:配置Prometheus, 不用任何代码,将数据直接写入
*
[
Telegraf 写入
](
/insert#telegraf
)
:配置Telegraf, 不用任何代码,将采集数据直接写入
*
[
EMQ X Broker
](
/insert#emq
)
:配置EMQ X,不用任何代码,就可将MQTT数据直接写入
*
[
HiveMQ Broker
](
/insert#hivemq
)
:配置HiveMQ,不用任何代码,就可将MQTT数据直接写入
...
...
documentation20/cn/05.insert/docs.md
浏览文件 @
7f8008a1
...
...
@@ -56,7 +56,6 @@ measurement,tag_set field_set timestamp
-
后缀为 i16,表示为 SMALLINT (INT16) 类型;
-
后缀为 i32,表示为 INT (INT32) 类型;
-
后缀为 i64,表示为 BIGINT (INT64) 类型;
-
后缀为 b,表示为 BOOL 类型。
*
t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。
timestamp 位置的时间戳通过后缀来声明时间精度,具体如下:
...
...
@@ -72,13 +71,15 @@ timestamp 位置的时间戳通过后缀来声明时间精度,具体如下:
st,t
1
=
3
i
64
,t
2
=
4
f
64
,t
3
=
"t3"
c
1
=
3
i
64
,c
3
=L
"passit"
,c
2
=
false
,c
4
=
4
f
64
1626006833639000000
ns
```
需要注意的是,如果描述数据类型后缀时使用了错误的大小写,或者为数据指定的数据类型有误,均可能引发报错提示而导致数据写入失败。
### Schemaless 的处理逻辑
Schemaless 按照如下原则来处理行数据:
1.
当 tag_set 中有 ID 字段时,该字段的值将作为数据子表的表名。
2.
没有 ID 字段时,将使用
`measurement + tag_value1 + tag_value2 + ...`
的 md5 值来作为子表名。
3.
如果指定的超级表名不存在,则 Schemaless 会创建这个超级表。
4.
如果指定的数据子表不存在,则 Schemaless 会
使用 tag values 创建这个数据
子表。
4.
如果指定的数据子表不存在,则 Schemaless 会
按照步骤 1 或 2 确定的子表名来创建
子表。
5.
如果数据行中指定的标签列或普通列不存在,则 Schemaless 会在超级表中增加对应的标签列或普通列(只增不减)。
6.
如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为 NULL。
7.
对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,那么 Schemaless 会增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。
...
...
documentation20/cn/08.connector/docs.md
浏览文件 @
7f8008a1
...
...
@@ -776,7 +776,7 @@ curl -u username:password -d '<SQL>' <ip>:<PORT>/rest/sql/[db_name]
-
data: 具体返回的数据,一行一行的呈现,如果不返回结果集,那么就仅有 [[affected_rows]]。data 中每一行的数据列顺序,与 column_meta 中描述数据列的顺序完全一致。
-
rows: 表明总共多少行数据。
column_meta 中的列类型说明:
<a
class=
"anchor"
id=
"column_meta"
></a>
column_meta 中的列类型说明:
*
1:BOOL
*
2:TINYINT
*
3:SMALLINT
...
...
documentation20/cn/12.taos-sql/02.udf/docs.md
0 → 100644
浏览文件 @
7f8008a1
# UDF(用户定义函数)
在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。
从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。
## 用 C/C++ 语言来定义 UDF
TDengine 提供 3 个 UDF 的源代码示例,分别为:
*
[
add_one.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c
)
*
[
abs_max.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c
)
*
[
sum_double.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c
)
### 无需中间变量的标量函数
[
add_one.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c
)
是结构最简单的 UDF 实现。其功能为:对传入的一个数据列(可能因 WHERE 子句进行了筛选)中的每一项,都输出 +1 之后的值,并且要求输入的列数据类型为 INT。
这一具体的处理逻辑在函数
`void add_one(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBUf, char* tsOutput, int* numOfOutput, short otype, short obytes, SUdfInit* buf)`
中定义。这类用于实现 UDF 的基础计算逻辑的函数,我们称为 udfNormalFunc,也就是对行数据块的标量计算函数。需要注意的是,udfNormalFunc 的参数项是固定的,用于按照约束完成与引擎之间的数据交换。
-
udfNormalFunc 中各参数的具体含义是:
*
data:存有输入的数据。
*
itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见
[
column_meta 中的列类型说明
](
https://www.taosdata.com/cn/documentation/connector#column_meta
)
。例如 4 用于表示 INT 型。
*
iBytes:输入数据中每个值会占用的字节数。
*
numOfRows:输入数据的总行数。
*
ts:主键时间戳在输入中的列数据。
*
dataOutput:输出数据的缓冲区。
*
interBuf:系统使用的中间临时缓冲区,通常用户逻辑无需对 interBuf 进行处理。
*
tsOutput:主键时间戳在输出时的列数据。
*
numOfOutput:输出数据的个数。
*
oType:输出数据的类型。取值含义与 itype 参数一致。
*
oBytes:输出数据中每个值会占用的字节数。
*
buf:计算过程的中间变量缓冲区。
其中 buf 参数需要用到一个自定义结构体 SUdfInit。在这个例子中,因为 add_one 的计算过程无需用到中间变量缓存,所以可以把 SUdfInit 定义成一个空结构体。
### 无需中间变量的聚合函数
[
abs_max.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c
)
实现的是一个聚合函数,功能是对一组数据按绝对值取最大值。
其计算过程为:与所在查询语句相关的数据会被分为多个行数据块,对每个行数据块调用 udfNormalFunc(在本例的实现代码中,实际函数名是
`abs_max`
),再将每个数据块的计算结果调用 udfMergeFunc(本例中,其实际的函数名是
`abs_max_merge`
)进行聚合,生成每个子表的聚合结果。如果查询指令涉及超级表,那么最后还会通过 udfFinalizeFunc(本例中,其实际的函数名是
`abs_max_finalize`
)再把子表的计算结果聚合为超级表的计算结果。
值得注意的是,udfNormalFunc、udfMergeFunc、udfFinalizeFunc 之间,函数名约定使用相同的前缀,此前缀即 udfNormalFunc 的实际函数名。udfMergeFunc 的函数名后缀
`_merge`
、udfFinalizeFunc 的函数名后缀
`_finalize`
,是 UDF 实现规则的一部分,系统会按照这些函数名后缀来调用相应功能。
-
udfMergeFunc 用于对计算中间结果进行聚合。本例中 udfMergeFunc 对应的实现函数为
`void abs_max_merge(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf)`
,其中各参数的具体含义是:
*
data:udfNormalFunc 的输出组合在一起的数据,也就成为了 udfMergeFunc 的输入。
*
numOfRows:data 中数据的行数。
*
dataOutput:输出数据的缓冲区。
*
numOfOutput:输出数据的个数。
*
buf:计算过程的中间变量缓冲区。
-
udfFinalizeFunc 用于对计算结果进行最终聚合。本例中 udfFinalizeFunc 对应的实现函数为
`void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfInit* buf)`
,其中各参数的具体含义是:
*
dataOutput:输出数据的缓冲区。对 udfFinalizeFunc 来说,其输入数据也来自于这里。
*
interBuf:系统使用的中间临时缓冲区,与 udfNormalFunc 中的同名参数含义一致。
*
numOfOutput:输出数据的个数。
*
buf:计算过程的中间变量缓冲区。
同样因为 abs_max 的计算过程无需用到中间变量缓存,所以同样是可以把 SUdfInit 定义成一个空结构体。
### 使用中间变量的聚合函数
[
sum_double.c
](
https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c
)
也是一个聚合函数,功能是对一组数据输出求和结果的倍数。
出于功能演示的目的,在这个用户定义函数的实现方法中,用到了中间变量缓冲区 buf。因此,在这个源代码文件中,SUdfInit 就不再是一个空的结构体,而是定义了缓冲区的具体存储内容。
也正是因为用到了中间变量缓冲区,因此就需要对这一缓冲区进行初始化和资源释放。具体来说,也即对应 udfInitFunc(本例中,其实际的函数名是
`sum_double_init`
)和 udfDestroyFunc(本例中,其实际的函数名是
`sum_double_destroy`
)。其函数名命名规则同样是采取以 udfNormalFunc 的实际函数名为前缀,以
`_init`
和
`_destroy`
为后缀。系统会在初始化和资源释放时调用对应名称的函数。
-
udfInitFunc 用于初始化中间变量缓冲区中的变量和内容。本例中 udfInitFunc 对应的实现函数为
`int sum_double_init(SUdfInit* buf)`
,其中各参数的具体含义是:
*
buf:计算过程的中间变量缓冲区。
-
udfDestroyFunc 用于释放中间变量缓冲区中的变量和内容。本例中 udfDestroyFunc 对应的实现函数为
`void sum_double_destroy(SUdfInit* buf)`
,其中各参数的具体含义是:
*
buf:计算过程的中间变量缓冲区。
注意,UDF 的实现过程中需要小心处理对中间变量缓冲区的使用,如果使用不当则有可能导致内存泄露或对资源的过度占用,甚至导致系统服务进程崩溃等。
### UDF 实现方式的规则总结
根据所要实现的 UDF 类型不同,用户所要实现的功能函数内容也会有所区别:
*
无需中间变量的标量函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc。
*
无需中间变量的聚合函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc、udfMergeFunc、udfFinalizeFunc。
*
使用中间变量的标量函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc。
*
使用中间变量的聚合函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc、udfMergeFunc、udfFinalizeFunc。
## 编译 UDF
用户定义函数的 C 语言源代码无法直接被 TDengine 系统使用,而是需要先编译为 .so 链接库,之后才能载入 TDengine 系统。
例如,按照上一章节描述的规则准备好了用户定义函数的源代码 add_one.c,那么可以执行如下指令编译得到动态链接库文件:
```
bash
gcc
-g
-O0
-fPIC
-shared
add_one.c
-o
add_one.so
```
这样就准备好了动态链接库 add_one.so 文件,可以供后文创建 UDF 时使用了。
## 在系统中管理和使用 UDF
### 创建 UDF
用户可以通过 SQL 指令在系统中加载客户端所在主机上的 UDF 函数库(不能通过 RESTful 接口或 HTTP 管理界面来进行这一过程)。一旦创建成功,则当前 TDengine 集群的所有用户都可以在 SQL 指令中使用这些函数。UDF 存储在系统的 MNode 节点上,因此即使重启 TDengine 系统,已经创建的 UDF 也仍然可用。
在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。
-
创建标量函数:
`CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);`
*
X:标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
*
Y:包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件);
*
Z:此函数计算结果的数据类型,使用数字表示,含义与上文中 udfNormalFunc 的 itype 参数一致;
*
B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。
-
创建聚合函数:
`CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);`
*
X:标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
*
Y:包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件);
*
Z:此函数计算结果的数据类型,使用数字表示,含义与上文中 udfNormalFunc 的 itype 参数一致;
*
B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。
### 管理 UDF
-
删除指定名称的用户定义函数:
`DROP FUNCTION ids(X);`
*
X:此参数的含义与 CREATE 指令中的 X 参数一致。
-
显示系统中当前可用的所有 UDF:
`SHOW FUNCTIONS;`
### 调用 UDF
在 SQL 指令中,可以直接以在系统中创建 UDF 时赋予的函数名来调用用户定义函数。例如:
```
sql
SELECT
X
(
c
)
FROM
table
/
stable
;
```
表示对名为 c 的数据列调用名为 X 的用户定义函数。SQL 指令中用户定义函数可以配合 WHERE 等查询特性来使用。
## UDF 的一些使用限制
在当前版本下,使用 UDF 存在如下这些限制:
1.
UDF 不能与系统内建的 SQL 函数混合使用;
2.
UDF 只支持以单个数据列作为输入;
3.
UDF 只要创建成功,就会被持久化存储到 MNode 节点中;
4.
无法通过 RESTful 接口来创建 UDF;
5.
UDF 在 SQL 中定义的函数名,必须与 .so 库文件实现中的接口函数名前缀保持一致,也即必须是 udfNormalFunc 的名称,而且不可与 TDengine 中已有的内建 SQL 函数重名。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录