作為一款高效簡潔的大數據平臺,時序數據庫 TDengine 的(de)(de)(de)使用(yong)體驗極為極為流(liu)暢,用(yong)戶可以輕(qing)松實(shi)現(xian)數(shu)據的(de)(de)(de)實(shi)時(shi)采集、存儲與分(fen)析(xi),快速獲取(qu)所需(xu)的(de)(de)(de)信息和洞察。但在追求最(zui)佳實(shi)踐的(de)(de)(de)過(guo)(guo)程中,我們(men)仍需(xu)關注一些關鍵問題。例如,多個設備是否應該向同一個子(zi)表寫入(ru)數(shu)據?在數(shu)據列過(guo)(guo)濾查詢與基于(yu)標簽的(de)(de)(de)過(guo)(guo)濾查詢之(zhi)間,效率的(de)(de)(de)差異有多大?此外,如何實(shi)現(xian)數(shu)據的(de)(de)(de)高(gao)效壓(ya)縮也是值得探討的(de)(de)(de)話題。本篇文章將通過(guo)(guo)具(ju)體的(de)(de)(de)案例分(fen)析(xi),詳細講(jiang)解(jie)這些問題,以期幫助(zhu)大家(jia)更深入(ru)地理解(jie)并高(gao)效使用(yong) TDengine。
場景描述
以某智能(neng)電表為(wei)例,可采集電壓、電流(liu)、漏電流(liu)、線路(lu)端子溫度、有功(gong)(gong)(gong)功(gong)(gong)(gong)率(lv)、功(gong)(gong)(gong)率(lv)因數(shu)、電量等參數(shu),數(shu)據每 2 分鐘(zhong)通過(guo) mqtt 上報(bao)一次,通過(guo) TDengine mqtt 可視化連接器(qi)進行采集,需(xu)要對各個累計電量和(he)平(ping)均功(gong)(gong)(gong)率(lv)進行統計。
需求描述
聚焦(jiao)用電量和(he)平均功率統計分(fen)析:
- 查詢用電量
- 年度總耗電量- 昨日用電量
- 用電趨勢,最近 30 天,每天的用電量
- 查詢近 24 小時的設備功率趨勢,按小時展示,每個小時的數據為:該小時單位內,每個設備平均功率的總和
建模和存在問題
建模內容

建模說明
- 客戶為了將超級表通用化,避免不同表具字段數目不統一情況,所以用了變量類型、 變量值和變量名稱 3 個字段,將寬表模型變成了單列模型
- 由于變量值包括整型、 浮點型 、離散型等,便將其設置為字符串類型 ,便于不同類型數據都能寫入
- 目前 var_name 列基數為 {current,power}
- cum_power:當前用電量
- power :功率
查詢效果
目(mu)前查詢近半年的數據每個(ge)月的累計值需(xu)要近 20 秒(miao)。
建模問題點評
客(ke)戶的建模(mo)方式雖(sui)然可(ke)以對(dui)各種場景適配,但不是(shi)最優建模(mo),存(cun)在以下(xia)問題:
- 對于來自同一電表的多個數據字段,將其分別處理成多個獨立的插入(insert)操作。在每次插入操作時,系統會利用本地時間生成精確到毫秒的時間戳,確保每個記錄都具有獨特的時間標記。然而,在處理大量電表數據的情況下,由于缺乏批量插入的策略,這種逐條記錄的插入方法可能會導致性能上的不足。
- 由于將不同采集量的數值匯總至同一字段,導致數值之間的差異極大,這不僅影響了一級增量(delta)壓縮的效率,還增加了存儲空間的占用。
- 當來自同一電表的不同采集量數據被存儲在同一字段中時,由于數據量的差異,無法實現在磁盤上的連續存儲。這種情況在查詢過程中會導致與磁盤的交互次數顯著增加,從而嚴重影響查詢效率。
- 由于所有采集值都被存儲在同一個字段中,每次查詢特定采集量時,都需要進行數據過濾。此外,相對于標簽字段,動態字段通常不支持索引,即使該字段理論上可以索引,但由于列的基數較低,建立的索引也無法提供有效的性能提升。在數據量較大的情況下,這將不可避免地導致查詢速度變慢。
建議建模內容
按照(zhao)寬(kuan)表(biao)(biao)形式(shi)展示(shi),對于不(bu)同(tong)類型的(de)設備,建立不(bu)同(tong)的(de)超(chao)級表(biao)(biao)。

相關語句
建表語句
創建超級表
create STABLE if not exists iot.device (ts timestamp, cum_power double, power double,mode TINYINT, note BINARY(500))TAGS ( project_id INT);
創建子表
create table serial_number using device tags(1)
查詢用電量
當月總耗電量
select sum(a) from (select spread(cum_power)as a from iot.device where project_id=1 and ts>to_char(now,"yyyy-mm-01") partition by tbname)
當年總耗電量
select sum(a) from (select spread(cum_power)as a from iot.device where project_id=1 and ts>to_char(now,"yyyy-01-01") partition by tbname)
昨日用電量
select sum(a) from (select spread(cum_power)as a from iot.device where project_id=1 and ts<timetruncate(now,1d) and ts>=(timetruncate(now,1d)-1d) partition by tbname)
用電趨勢,最近(jin) 30 天、每天的用電量
select last(t),sum(a) from (select _wstart as t,spread(cum_power)as a from iot.device where project_id=1 and ts<now and ts>=(timetruncate(now,1d)-30d) partition by tbname interval(1d) order by t) interval(1d)
查詢功率相關
查詢近 24 小時的(de)設(she)備(bei)功(gong)率(lv)(lv)趨勢(shi)——按小時展(zhan)示(shi)每(mei)個設(she)備(bei)平均(jun)功(gong)率(lv)(lv)的(de)總和
select last(t),sum(a) from(select _wstart as t,avg(power)as a from iot.device where project_id=1 and ts<now and ts>=(timetruncate(now,1h)-24h) partition by tbname interval(1h) order by t)interval(1h)
總結
TDengine 的(de)高效寫入、查詢性(xing)能(neng)和(he)數據壓縮能(neng)力(li),得益于(yu)其(qi)創新(xin)的(de)“一個設(she)(she)備一張(zhang)表(biao)”的(de)設(she)(she)計(ji)理(li)(li)念(nian)(nian)。因此,在進(jin)行數據建(jian)模時(shi),我們應以這一理(li)(li)念(nian)(nian)為指導,確保系統的(de)長期(qi)穩(wen)定(ding)性(xing)和(he)性(xing)能(neng)最(zui)優化,有效預防未來數據量劇增時(shi)可能(neng)出(chu)現(xian)的(de)結(jie)構性(xing)調整需求,從(cong)而(er)減少潛(qian)在的(de)復(fu)雜性(xing)和(he)成本。


























