无码人妻精品一区二区三18禁,影音先锋男人AV橹橹色,污污污污污污www网站免费,日韩成人av无码一区二区三区,欧美性受xxxx狂喷水

如何在 TDengine 中編寫自定義函數?

TAOS Data

2022-10-11 / , ,

小 T 導讀:雖然 TDengine 已經提(ti)供了(le)(le)非常多的常用(yong)計(ji)(ji)算(suan)函(han)數,但是在(zai)具(ju)體實(shi)踐(jian)中,企業的開發團隊往往會(hui)因(yin)為自己特(te)(te)殊的業務需(xu)求,需(xu)要特(te)(te)有(you)的計(ji)(ji)算(suan)函(han)數,這時(shi)候(hou),支(zhi)持自定義函(han)數功(gong)能就(jiu)特(te)(te)別重(zhong)要了(le)(le)。本文將介紹 TDengine 3.0 支(zhi)持的 UDF 機(ji)制(zhi)。

在使用 TDengine 這款時序數據庫(Time Series Database, TSDB)的時候,我(wo)們(men)經常會用到各種內置(zhi)函數(shu),通過在數(shu)據(ju)庫(ku)中完(wan)成(cheng)很多計算,可以(yi)大(da)大(da)簡化數(shu)據(ju)庫(ku)應用層(ceng)的開發(fa)工作。

TDengine 提供(gong)了大量的內置函數,可(ke)以分為幾個大類:

  • 單行函數:單行函數為查詢結果中的每一行返回一個結果行
    • 數學函數:如 ABS、SIN、COS、LOG、POW 等
    • 字符串函數:如 CHAR_LENGTH、CONCAT、LOWER、SUBSTR、UPPER 等
    • 轉換函數:如 CAST、TO_JSON、TO_UNIXTIMESTAMP 等
    • 時間和日期函數:NOW、TIMEDIFF、TIMEZONE、TODAY 等
  • 聚合函數:聚合函數為查詢結果集的每一個分組返回單個結果行
    • 如 AVG、COUNT、STDDEV、SUM 等
  • 選擇函數
  • 時序數據特有函數
  • 系統信息函數

雖然(ran) TDengine 已經提供了這么多(duo)常用的計(ji)算(suan)函數,但(dan)是在具體實踐中,企業的開發團隊往往會因為自己特殊(shu)的業務需(xu)求,需(xu)要特有的計(ji)算(suan)函數,這時候,支(zhi)持自定義函數功能(neng)就特別重(zhong)要了。

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

利用 UDF(User Defined Function) 功能,TDengine 可(ke)以插入(ru)(ru)用戶編寫(xie)的處理代碼(ma)并在查詢(xun)中使(shi)用它們,這樣就能很方便地解決特殊應(ying)用場景(jing)中的使(shi)用需求(qiu)。 UDF 通常以數據表中的一列數據做為輸入(ru)(ru),同時支(zhi)持以嵌套子查詢(xun)的結果(guo)作為輸入(ru)(ru)。

TDengine 支持通過 C/C++ 語(yu)言來定義 UDF。TDengine 3.0 優化了(le)相關機制,所以本文描述的特性適用于(yu) 3.0 及(ji)以上版本。

基本概念

用戶(hu)可以通(tong)過 UDF 實現兩(liang)類函(han)數(shu)(shu):標量(liang)函(han)數(shu)(shu)和(he)聚合(he)函(han)數(shu)(shu)。標量(liang)函(han)數(shu)(shu)對(dui)每行數(shu)(shu)據輸出一(yi)個值(zhi),如求(qiu)絕對(dui)值(zhi) abs,正(zheng)弦(xian)函(han)數(shu)(shu) sin,字符(fu)串拼接函(han)數(shu)(shu) concat 等。聚合(he)函(han)數(shu)(shu)對(dui)多行數(shu)(shu)據進行輸出一(yi)個值(zhi),如求(qiu)平均數(shu)(shu) avg,最大值(zhi) max 等。

實現 UDF 時,需(xu)要實現規定的接口函數

  • 標量函數需要實現標量接口函數 scalarfn
  • 聚合函數需要實現聚合接口函數 aggfn_start、aggfn、aggfn_finish
  • 如果需要初始化,實現 udf_init;如果需要清理工作,實現 udf_destroy

接口函數(shu)的(de)名稱是(shi) UDF 名稱,或者(zhe)是(shi) UDF 名稱和(he)特定后綴(_start, _finish, _init, _destroy)的(de)連接。列(lie)表中的(de)scalarfn、aggfn、udf需(xu)要替(ti)換成udf函數(shu)名。

標量接口函數

int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)

其(qi)中 scalarFn 是函數(shu)名的(de)占位符。這個函數(shu)對(dui)數(shu)據塊進行標量計算(suan),通過(guo)設置(zhi)resultColumn結(jie)構體中的(de)變量設置(zhi)值。

參數的具體含義是:

  • inputDataBlock: 輸入的數據塊
  • resultColumn: 輸出列

聚合接口函數

int32_t aggfn_start(SUdfInterBuf *interBuf)

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

int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)

其中 aggfn 是函數(shu)(shu)名的占位符。首先調(diao)用(yong)aggfn_start生(sheng)成結(jie)果(guo)(guo)buffer,然后相(xiang)關的數(shu)(shu)據(ju)(ju)(ju)會被分為多個行(xing)數(shu)(shu)據(ju)(ju)(ju)塊,對每個數(shu)(shu)據(ju)(ju)(ju)塊調(diao)用(yong) aggfn 用(yong)數(shu)(shu)據(ju)(ju)(ju)塊更新中間結(jie)果(guo)(guo),最后再調(diao)用(yong) aggfn_finish 從(cong)中間結(jie)果(guo)(guo)產(chan)生(sheng)最終結(jie)果(guo)(guo),最終結(jie)果(guo)(guo)只能含 0 或 1 條結(jie)果(guo)(guo)數(shu)(shu)據(ju)(ju)(ju)。

參數的具體含義是:

  • interBuf:中間結果 buffer。
  • inputBlock:輸入的數據塊。
  • newInterBuf:新的中間結果buffer。
  • result:最終結果。

UDF 初始化和銷毀

int32_t udf_init()

int32_t udf_destroy()

其中 udf 是函數(shu)名的占位符。udf_init 完成初始(shi)化工(gong)作(zuo)(zuo)。 udf_destroy 完成清理工(gong)作(zuo)(zuo)。如果沒(mei)有初始(shi)化工(gong)作(zuo)(zuo),無需定義udf_init函數(shu)。

如果(guo)沒(mei)有清理(li)工作(zuo),無需定義(yi)udf_destroy函數。 篇幅所限(xian),相關數據(ju)結構的定義(yi)可以參考 UDF 文檔。

編譯 UDF

用戶(hu)定義函數的 C 語言源代(dai)碼無(wu)法直接被 TDengine 系統(tong)所使用,而是需(xu)要先編譯為 動態鏈(lian)接庫(ku),之后才能載入 TDengine 系統(tong)。

假設我們編寫了自(zi)定義(yi)函數(shu),保存在(zai) add_one.c 文件中(zhong),在(zai) Linux 上可以這樣編譯:

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

創建 UDF

用(yong)戶(hu)可(ke)以通(tong)過 SQL 指令在(zai)系統(tong)中加載(zai)客(ke)戶(hu)端所在(zai)主機上的(de) UDF 函數(shu)庫。一旦創建成功,則當前 TDengine 集群的(de)所有用(yong)戶(hu)都可(ke)以在(zai) SQL 指令中使用(yong)這些(xie)函數(shu)。UDF 存儲在(zai)系統(tong)的(de) MNode 節點上,因(yin)此即使重啟 TDengine 系統(tong),已(yi)經創建的(de) UDF 也仍然可(ke)用(yong)。

在(zai)創建 UDF 時,需要(yao)區分標量函數和聚(ju)合函數。

  • 創建標量函數
CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type;

例如(ru),如(ru)下語句可(ke)以把(ba) libbitand.so 創建為系統中可(ke)用(yong)的 UDF:

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

例(li)如(ru),如(ru)下(xia)語句可以把(ba) libl2norm.so 創建為系統中可用的 UDF:

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

如果不(bu)再需要(yao),可(ke)以通過 DROP 指令刪除所創建的 UDF。

DROP FUNCTION function_name;

使用 UDF

在 SQL 指令中(zhong),可(ke)以直接以在系統中(zhong)創建 UDF 時賦予的(de)函(han)數(shu)名(ming)來(lai)調(diao)用用戶(hu)定(ding)義函(han)數(shu)。例(li)如:

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

表示對名為 c1、c2 的數據列調用名為 X 的用戶(hu)定義函(han)數。SQL 指令中用戶(hu)定義函(han)數可(ke)以配(pei)合(he) WHERE 等查詢特性來使用。

歡迎下載試用 TDengine 3.0,并嘗試編(bian)寫一個(ge)自定義函數。

歡迎(ying)添加小T微信:tdengine,加入物聯網技(ji)術(shu)討(tao)論群,第一時間了解 TDengine 官方(fang)信息,與關注(zhu)前沿技(ji)術(shu)的同學們共同探討(tao)新技(ji)術(shu)、新玩(wan)法(fa)。

TDengine Database