作者:陳玉|濤思數(shù)據(jù)
小T導(dǎo)讀:作為一款高性能的時(shí)序數(shù)據(jù)庫(kù)(Time-Series Database),TDengine提供了強(qiáng)大的數(shù)據(jù)分析功能。在TDengine官網(wǎng)的第一個(gè)章節(jié)里,有這樣的描述:“無(wú)論是十年前還是一秒鐘前的數(shù)據(jù),指定時(shí)間范圍即可查詢。數(shù)據(jù)可在時(shí)間軸上或多個(gè)設(shè)備上進(jìn)行聚合?!?
今天,我們的主角就是上文中“可在時(shí)間軸上”聚合的強(qiáng)大函數(shù)——INTERVAL。
INTERVAL是TDengine Database的一大重要功能,可以幫助我們實(shí)現(xiàn)降低數(shù)據(jù)采集頻率的功能——也就是降采樣。舉個(gè)簡(jiǎn)單的例子:假設(shè)我們有某個(gè)設(shè)備一年的數(shù)據(jù),時(shí)間數(shù)據(jù)的頻率是1天,那么就是一共365條數(shù)據(jù)?,F(xiàn)在,如果我們想按照月這個(gè)頻率統(tǒng)計(jì),那么數(shù)據(jù)量就變成了12條。
根據(jù)官網(wǎng)的語(yǔ)法描述,相關(guān)的功能模塊有三個(gè):
- INTERVAL本身
- SLIDING
- INTERVAL OFFSET

對(duì)于以處理時(shí)序數(shù)據(jù)為根基的時(shí)序數(shù)據(jù)庫(kù)來(lái)說,如何靈活的利用時(shí)間頻率來(lái)計(jì)算分析數(shù)據(jù)實(shí)在是太重要了。下面我們圍繞上面三個(gè)功能模塊,分別舉一個(gè)簡(jiǎn)單的應(yīng)用場(chǎng)景的例子并做出具體說明:
1.INTERVAL:查詢溫度傳感器t1記錄的溫度、壓力每五分鐘的平均值
select avg(t), avg(p) from t1 interval(5m);
這是一個(gè)最簡(jiǎn)單的使用情況,INTERVAL負(fù)責(zé)指定時(shí)間范圍窗口,由AVG這種聚合函數(shù)來(lái)計(jì)算這個(gè)時(shí)間范圍內(nèi)的平均值。也可以換成MAX/MIN這類的選擇函數(shù),來(lái)統(tǒng)計(jì)出這個(gè)時(shí)間范圍內(nèi)的最大值/最小值。(在TAOS SQL中,聚合函數(shù)指的是COUNT/AVG/TWA/SUM等用于從數(shù)據(jù)集中匯合再計(jì)算的函數(shù),選擇函數(shù)是指 MIN/MAX/FIRST/LAST/LAST_ROW等用于從數(shù)據(jù)集中篩選結(jié)果的函數(shù)。)
INTERVAL本質(zhì)上就是group by的時(shí)間版本,所以一定需要配合上述聚合或選擇函數(shù)來(lái)使用。INTERVAL后面的時(shí)間單位可以是 a(毫秒)、s(秒)、m(分)、h(小時(shí))、d(自然日)、w(周), n(自然月) 和 y(自然年)。(暫時(shí)還不支持自然周,interval(1w) 目前等效于interval(7d))。
2.SLIDING:可以統(tǒng)計(jì)類似股票市場(chǎng)的均線
select avg(t) from stockmarket interval(5d) sliding(1d)。
上述語(yǔ)句的實(shí)際含義是統(tǒng)計(jì)股市上某股票所有每過一天的5天的價(jià)格平均值,把這些值連起來(lái),就是大家熟知的五日均線了。
在上述計(jì)算過程中,SLIDING起到了非常關(guān)鍵的作用。我們已經(jīng)知道,INTERVAL 的值負(fù)責(zé)指定每次執(zhí)行查詢的時(shí)間窗口。SLIDING則代表著指定窗口向前滑動(dòng)的時(shí)間。如下圖所示:

t0s,t1s,t2s分別是三個(gè)時(shí)間窗口的起點(diǎn),t0e,t1e,t2e分別是三個(gè)時(shí)間窗口的終點(diǎn)。當(dāng)我們?cè)诓樵冎胁恢付⊿LIDING的值時(shí),它默認(rèn)等于INTERVAL VALUE。也即是說在第一個(gè)例子當(dāng)中的select avg(t), avg(p) from t1 interval(5m)等效于select avg(t), avg(p) from t1 interval(5m) sliding (5m);
3.INTERVAL OFFSET:統(tǒng)計(jì)某個(gè)設(shè)備在其他時(shí)區(qū)(向西相差三個(gè)時(shí)區(qū))的一個(gè)月的總數(shù)據(jù)量
select sum(t) from t1 interval(1n,3h) ;
這個(gè)SQL的語(yǔ)義是:統(tǒng)計(jì)當(dāng)前服務(wù)端所在時(shí)區(qū)向西推動(dòng)三個(gè)時(shí)區(qū)后的這個(gè)設(shè)備的該月總數(shù)據(jù)。OFFSET 3h代表的是OFFSET值為3h,也就是說這個(gè)SQL適用于統(tǒng)計(jì)不同時(shí)區(qū)的自然月數(shù)據(jù)統(tǒng)計(jì)。
INTERVAL OFFSET會(huì)相對(duì)復(fù)雜一些。想了解的話,需要先更多地了解INTERVAL和時(shí)區(qū)的關(guān)系。
如果INTERVAL的值是自然日(d),自然月(n),自然年(y),那么它就是對(duì)齊TDengine服務(wù)端所在時(shí)區(qū)的0點(diǎn)開始做的窗口切分,如下圖所示:不論當(dāng)前所屬哪個(gè)時(shí)區(qū),所有時(shí)間戳列的起始時(shí)間都是0點(diǎn)。

但是,如果是以時(shí)分秒及以下的時(shí)間單位去切分窗口,那么INTERVAL的值則是對(duì)齊從UTC-0時(shí)間的00:00:00.000開始切分的時(shí)間窗口。
如下圖所示,時(shí)間戳列的起始時(shí)間都是8點(diǎn),這是因?yàn)門Dengine客戶端的時(shí)區(qū)為UTC-8,標(biāo)準(zhǔn)時(shí)間為0點(diǎn)的時(shí)候,東八區(qū)為8點(diǎn)(注意:在POSIX標(biāo)準(zhǔn)中,UTC-8代表東八區(qū),與平時(shí)的習(xí)慣性表達(dá)不一樣)。

這個(gè)場(chǎng)景,就是官網(wǎng)文檔中這段話的含義:
TDengine 中時(shí)間戳的時(shí)區(qū)總是由客戶端進(jìn)行處理,與服務(wù)端無(wú)關(guān)。具體來(lái)說,客戶端會(huì)對(duì) SQL 語(yǔ)句中的時(shí)間戳進(jìn)行時(shí)區(qū)轉(zhuǎn)換,轉(zhuǎn)為 UTC-0時(shí)區(qū)的Unix時(shí)間戳再交由服務(wù)端進(jìn)行寫入和查詢;在讀取數(shù)據(jù)時(shí),服務(wù)端也是采用 UTC-0時(shí)區(qū)提供的原始數(shù)據(jù),客戶端收到后再根據(jù)本地設(shè)置,把時(shí)間戳轉(zhuǎn)換為本地系統(tǒng)所要求的時(shí)區(qū)進(jìn)行顯示。
總結(jié)一下就是:TDengine以時(shí)間戳形式來(lái)存儲(chǔ)時(shí)間數(shù)據(jù),時(shí)間戳本身是一個(gè)和時(shí)區(qū)無(wú)關(guān)的東西,但是由于TDengine要把數(shù)據(jù)查詢出來(lái)展示給世界上不同地區(qū)的用戶看,就和時(shí)區(qū)有關(guān)系了。在INTERVAL中,如果是自然日,自然月,自然年,均以TDengine服務(wù)端所在時(shí)區(qū)的0點(diǎn)為起始時(shí)間進(jìn)行時(shí)間窗口區(qū)分。如果是以h(小時(shí))及以下為單位切分窗口,那么進(jìn)行窗口切分的起始時(shí)間就是UTC時(shí)區(qū)的0點(diǎn)。
不論是哪個(gè)時(shí)區(qū)的客戶端,最終的計(jì)算列結(jié)果都是一致的,只是由于時(shí)區(qū)不同,所以顯示的時(shí)候在時(shí)間戳列上會(huì)有一些偏差。因此我們強(qiáng)烈建議,非特殊情況下,客戶端服務(wù)器和服務(wù)端服務(wù)器的時(shí)區(qū)要保持一致,從而使得兩邊的查詢顯示是一致的,從而減少不必要的誤解。
比如,左側(cè)客戶端count(*)看起來(lái)應(yīng)該是1 4 2,實(shí)際上卻是4和3。這就是因?yàn)閮蛇厱r(shí)區(qū)不一致導(dǎo)致的視覺差異。這時(shí)候就要以服務(wù)端的顯示為準(zhǔn):6月30日有4條數(shù)據(jù),7月1日有3條數(shù)據(jù)——TDengine服務(wù)端所在服務(wù)器的查詢結(jié)果,永遠(yuǎn)是所見即所得的正確。

搞清楚了INTERVAL對(duì)于自然日月年和時(shí)分秒的不同切分邏輯后,接下來(lái),我們終于可以說一下OFFSET了。
OFFSET其實(shí)是INTERVAL功能的偏移值。通過調(diào)整OFFSET值,就可以在時(shí)間軸上自由選擇時(shí)間窗口的起始點(diǎn)。從而完成不同時(shí)區(qū)的數(shù)據(jù)分析統(tǒng)計(jì)。
比如,服務(wù)端當(dāng)前的時(shí)區(qū)是東八區(qū),但是我們想知道在東五區(qū)時(shí)區(qū)下,設(shè)備t1的每個(gè)月數(shù)據(jù)總量。就可以這樣寫:
select sum(t) from t1 interval(1n,3h) ;
但是由于OFFSET目前暫時(shí)不能支持負(fù)值,所以時(shí)間窗口的起點(diǎn)只能從時(shí)區(qū)東向西偏移。因此如果想用時(shí)區(qū)偏移功能統(tǒng)計(jì)24個(gè)時(shí)區(qū),暫時(shí)可以把服務(wù)端所在的服務(wù)器時(shí)區(qū)設(shè)置為東十二區(qū)(UTC-12)。
作為一個(gè)定位國(guó)際化的產(chǎn)品,我們TDengine后面會(huì)繼續(xù)完善相關(guān)的功能。如果想了解更多更具體的細(xì)節(jié),可以在GitHub上查看相關(guān)源代碼。



互聯(lián)網(wǎng).png)



-1.png)




.png)


證.png)


伙伴.png)
伙伴.png)
伙伴.png)



