六月婷婷AV,国产偷窥猎奇福利二区,日韩三级片。,好吊色网站,日韩成人中文在线视频,国产亚洲午夜啪啪,亚洲欧美另类国产精品,国产成人av1,任你艹在线观看

如何在 TDengine 中編寫(xiě)自定義函數(shù)?

小 T 導(dǎo)讀:雖然 TDengine 已經(jīng)提供了非常多的常用計(jì)算函數(shù),但是在具體實(shí)踐中,企業(yè)的開(kāi)發(fā)團(tuán)隊(duì)往往會(huì)因?yàn)樽约禾厥獾臉I(yè)務(wù)需求,需要特有的計(jì)算函數(shù),這時(shí)候,支持自定義函數(shù)功能就特別重要了。本文將介紹 TDengine 3.0 支持的 UDF 機(jī)制。

在使用 TDengine 這款時(shí)序數(shù)據(jù)庫(kù)(Time Series Database, TSDB)的時(shí)候,我們經(jīng)常會(huì)用到各種內(nèi)置函數(shù),通過(guò)在數(shù)據(jù)庫(kù)中完成很多計(jì)算,可以大大簡(jiǎn)化數(shù)據(jù)庫(kù)應(yīng)用層的開(kāi)發(fā)工作。

TDengine 提供了大量的內(nèi)置函數(shù),可以分為幾個(gè)大類(lèi):

  • 單行函數(shù):?jiǎn)涡泻瘮?shù)為查詢(xún)結(jié)果中的每一行返回一個(gè)結(jié)果行
    • 數(shù)學(xué)函數(shù):如 ABS、SIN、COS、LOG、POW 等
    • 字符串函數(shù):如 CHAR_LENGTH、CONCAT、LOWER、SUBSTR、UPPER 等
    • 轉(zhuǎn)換函數(shù):如 CAST、TO_JSON、TO_UNIXTIMESTAMP 等
    • 時(shí)間和日期函數(shù):NOW、TIMEDIFF、TIMEZONE、TODAY 等
  • 聚合函數(shù):聚合函數(shù)為查詢(xún)結(jié)果集的每一個(gè)分組返回單個(gè)結(jié)果行
    • 如 AVG、COUNT、STDDEV、SUM 等
  • 選擇函數(shù)
  • 時(shí)序數(shù)據(jù)特有函數(shù)
  • 系統(tǒng)信息函數(shù)

雖然 TDengine 已經(jīng)提供了這么多常用的計(jì)算函數(shù),但是在具體實(shí)踐中,企業(yè)的開(kāi)發(fā)團(tuán)隊(duì)往往會(huì)因?yàn)樽约禾厥獾臉I(yè)務(wù)需求,需要特有的計(jì)算函數(shù),這時(shí)候,支持自定義函數(shù)功能就特別重要了。

本文將具體介紹如何在 TDengine 中定義并使用自定義函數(shù)。

利用 UDF(User Defined Function) 功能,TDengine 可以插入用戶(hù)編寫(xiě)的處理代碼并在查詢(xún)中使用它們,這樣就能很方便地解決特殊應(yīng)用場(chǎng)景中的使用需求。 UDF 通常以數(shù)據(jù)表中的一列數(shù)據(jù)做為輸入,同時(shí)支持以嵌套子查詢(xún)的結(jié)果作為輸入。

TDengine 支持通過(guò) C/C++ 語(yǔ)言來(lái)定義 UDF。TDengine 3.0 優(yōu)化了相關(guān)機(jī)制,所以本文描述的特性適用于 3.0 及以上版本。

基本概念

用戶(hù)可以通過(guò) UDF 實(shí)現(xiàn)兩類(lèi)函數(shù):標(biāo)量函數(shù)和聚合函數(shù)。標(biāo)量函數(shù)對(duì)每行數(shù)據(jù)輸出一個(gè)值,如求絕對(duì)值 abs,正弦函數(shù) sin,字符串拼接函數(shù) concat 等。聚合函數(shù)對(duì)多行數(shù)據(jù)進(jìn)行輸出一個(gè)值,如求平均數(shù) avg,最大值 max 等。

實(shí)現(xiàn) UDF 時(shí),需要實(shí)現(xiàn)規(guī)定的接口函數(shù)

  • 標(biāo)量函數(shù)需要實(shí)現(xiàn)標(biāo)量接口函數(shù) scalarfn
  • 聚合函數(shù)需要實(shí)現(xiàn)聚合接口函數(shù) aggfn_start、aggfn、aggfn_finish
  • 如果需要初始化,實(shí)現(xiàn) udf_init;如果需要清理工作,實(shí)現(xiàn) udf_destroy

接口函數(shù)的名稱(chēng)是 UDF 名稱(chēng),或者是 UDF 名稱(chēng)和特定后綴(_start, _finish, _init, _destroy)的連接。列表中的scalarfn、aggfn、udf需要替換成udf函數(shù)名。

標(biāo)量接口函數(shù)

int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)

其中 scalarFn 是函數(shù)名的占位符。這個(gè)函數(shù)對(duì)數(shù)據(jù)塊進(jìn)行標(biāo)量計(jì)算,通過(guò)設(shè)置resultColumn結(jié)構(gòu)體中的變量設(shè)置值。

參數(shù)的具體含義是:

  • inputDataBlock: 輸入的數(shù)據(jù)塊
  • resultColumn: 輸出列

聚合接口函數(shù)

int32_t aggfn_start(SUdfInterBuf *interBuf)

int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf)

int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)

其中 aggfn 是函數(shù)名的占位符。首先調(diào)用aggfn_start生成結(jié)果buffer,然后相關(guān)的數(shù)據(jù)會(huì)被分為多個(gè)行數(shù)據(jù)塊,對(duì)每個(gè)數(shù)據(jù)塊調(diào)用 aggfn 用數(shù)據(jù)塊更新中間結(jié)果,最后再調(diào)用 aggfn_finish 從中間結(jié)果產(chǎn)生最終結(jié)果,最終結(jié)果只能含 0 或 1 條結(jié)果數(shù)據(jù)。

參數(shù)的具體含義是:

  • interBuf:中間結(jié)果 buffer。
  • inputBlock:輸入的數(shù)據(jù)塊。
  • newInterBuf:新的中間結(jié)果buffer。
  • result:最終結(jié)果。

UDF 初始化和銷(xiāo)毀

int32_t udf_init()

int32_t udf_destroy()

其中 udf 是函數(shù)名的占位符。udf_init 完成初始化工作。 udf_destroy 完成清理工作。如果沒(méi)有初始化工作,無(wú)需定義udf_init函數(shù)。

如果沒(méi)有清理工作,無(wú)需定義udf_destroy函數(shù)。 篇幅所限,相關(guān)數(shù)據(jù)結(jié)構(gòu)的定義可以參考 UDF 文檔。

編譯 UDF

用戶(hù)定義函數(shù)的 C 語(yǔ)言源代碼無(wú)法直接被 TDengine 系統(tǒng)所使用,而是需要先編譯為 動(dòng)態(tài)鏈接庫(kù),之后才能載入 TDengine 系統(tǒng)。

假設(shè)我們編寫(xiě)了自定義函數(shù),保存在 add_one.c 文件中,在 Linux 上可以這樣編譯:

gcc -g -O0 -fPIC -shared add_one.c -o add_one.so

創(chuàng)建 UDF

用戶(hù)可以通過(guò) SQL 指令在系統(tǒng)中加載客戶(hù)端所在主機(jī)上的 UDF 函數(shù)庫(kù)。一旦創(chuàng)建成功,則當(dāng)前 TDengine 集群的所有用戶(hù)都可以在 SQL 指令中使用這些函數(shù)。UDF 存儲(chǔ)在系統(tǒng)的 MNode 節(jié)點(diǎn)上,因此即使重啟 TDengine 系統(tǒng),已經(jīng)創(chuàng)建的 UDF 也仍然可用。

在創(chuàng)建 UDF 時(shí),需要區(qū)分標(biāo)量函數(shù)和聚合函數(shù)。

  • 創(chuàng)建標(biāo)量函數(shù)
CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type;

例如,如下語(yǔ)句可以把 libbitand.so 創(chuàng)建為系統(tǒng)中可用的 UDF:

CREATE FUNCTION bit_and AS "/home/taos/udf_example/libbitand.so" OUTPUTTYPE INT;
  • 創(chuàng)建聚合函數(shù):
CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ];

例如,如下語(yǔ)句可以把 libl2norm.so 創(chuàng)建為系統(tǒng)中可用的 UDF:

CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8;

如果不再需要,可以通過(guò) DROP 指令刪除所創(chuàng)建的 UDF。

DROP FUNCTION function_name;

使用 UDF

在 SQL 指令中,可以直接以在系統(tǒng)中創(chuàng)建 UDF 時(shí)賦予的函數(shù)名來(lái)調(diào)用用戶(hù)定義函數(shù)。例如:

SELECT X(c1,c2) FROM table/stable;

表示對(duì)名為 c1、c2 的數(shù)據(jù)列調(diào)用名為 X 的用戶(hù)定義函數(shù)。SQL 指令中用戶(hù)定義函數(shù)可以配合 WHERE 等查詢(xún)特性來(lái)使用。

歡迎下載試用 TDengine 3.0,并嘗試編寫(xiě)一個(gè)自定義函數(shù)。

歡迎添加小T微信:tdengine,加入物聯(lián)網(wǎng)技術(shù)討論群,第一時(shí)間了解 TDengine 官方信息,與關(guān)注前沿技術(shù)的同學(xué)們共同探討新技術(shù)、新玩法。

TDengine Database