數據模型
數據模型
我們以風電場物聯網場景為例,說明如何在 IoTDB 中創建一個正確的數據模型。
根據企業組織結構和設備實體層次結構,我們將其物聯網數據模型表示為如下圖所示的屬性層級組織結構,即電力集團層-風電場層-實體層-物理量層。其中 ROOT 為根節點,物理量層的每一個節點為葉子節點。IoTDB 采用樹形結構定義數據模式,以從 ROOT 節點到葉子節點的路徑來命名一個時間序列,層次間以“.”連接。例如,下圖最左側路徑對應的時間序列名稱為ROOT.ln.wf01.wt01.status。

在上圖所描述的實際場景中,有許多實體所采集的物理量相同,即具有相同的工況名稱和類型,因此,可以聲明一個元數據模板來定義可采集的物理量集合。在實踐中,元數據模板的使用可幫助減少元數據的資源占用,詳細內容參見 元數據模板。
IoTDB 模型結構涉及的基本概念在下文將做詳細敘述。
數據庫(Database)
用戶可以將任意前綴路徑設置成數據庫。如有 4 條時間序列root.ln.wf01.wt01.status, root.ln.wf01.wt01.temperature, root.ln.wf02.wt02.hardware, root.ln.wf02.wt02.status,路徑root.ln下的兩個實體 wf01, wf02可能屬于同一個業主,或者同一個制造商,這時候就可以將前綴路徑root.ln指定為一個數據庫。未來root.ln下增加了新的實體,也將屬于該數據庫。
一個 database 中的所有數據會存儲在同一批文件夾下,不同 database 的數據會存儲在磁盤的不同文件夾下,從而實現物理隔離。一般情況下建議設置 1 個 database。
注意 1:不允許將一個完整路徑(如上例的
root.ln.wf01.wt01.status) 設置成 database。注意 2:一個時間序列其前綴必須屬于某個 database。在創建時間序列之前,用戶必須設定該序列屬于哪個database。只有設置了 database 的時間序列才可以被持久化在磁盤上。
注意 3:被設置為數據庫的路徑總字符數不能超過64,包括路徑開頭的
root.這5個字符。
一個前綴路徑一旦被設定成 database 后就不可以再更改這個 database 的設定。
一個 database 設定后,其對應的前綴路徑的祖先層級與孩子及后裔層級也不允許再設置 database(如,root.ln設置 database 后,root 層級與root.ln.wf01不允許被設置為 database)。
Database 節點名只支持中英文字符、數字和下劃線的組合。例如root.數據庫_1 。
無模式寫入:可以在未定義元數據時, 通過 insert 語句直接寫入數據,數據庫中將自動識別并注冊所需的元數據,實現自動建模。
設備(Device)
一個物理設備,也稱實體(Entity),是在實際場景中擁有物理量的設備或裝置。在 IoTDB 當中,所有的物理量都有其對應的歸屬實體。實體無需手動創建,默認為倒數第二層。實體是管理的一組時間序列的組合,可以是一個物理設備、測量裝置、傳感器集合等。
物理量(Measurement)
物理量,也稱工況或字段(field),是在實際場景中檢測裝置所記錄的測量信息,且可以按一定規律變換成為電信號或其他所需形式的信息輸出并發送給 IoTDB。在 IoTDB 當中,存儲的所有數據及路徑,都是以物理量為單位進行組織。
時間序列
時間戳 (Timestamp)
時間戳是一個數據到來的時間點,其中包括絕對時間戳和相對時間戳,詳細描述參見 數據類型文檔。
數據點(Data Point)
一個“時間戳-值”對。
時間序列(Timeseries)
一個物理實體的某個物理量在時間軸上的記錄,是數據點的序列。
一個實體的一個物理量對應一個時間序列,即實體+物理量=時間序列。
時間序列也被稱測點(meter)、時間線(timeline)。實時數據庫中常被稱作標簽(tag)、參數(parameter)。 IoTDB管理的測點數量可達數十億以上。
例如,ln 電力集團、wf01 風電場的實體 wt01 有名為 status 的物理量,則它的時間序列可以表示為:root.ln.wf01.wt01.status。
對齊時間序列(Aligned Timeseries)
在實際應用中,存在某些實體的多個物理量同時采樣,形成一組時間列相同的時間序列,這樣的一組時間序列在Apache IoTDB中可以建模為對齊時間序列。
在插入數據時,一組對齊序列的時間戳列在內存和磁盤中僅需存儲一次,而不是每個時間序列存儲一次。
對齊的一組時間序列最好同時創建。
不可以在對齊序列所屬的實體下創建非對齊的序列,不可以在非對齊序列所屬的實體下創建對齊序列。
查詢數據時,可以對于每一條時間序列單獨查詢。
插入數據時,對齊的時間序列中某列的某些行允許有空值。

在后續數據定義語言、數據操作語言和 Java 原生接口章節,將對涉及到對齊時間序列的各種操作進行逐一介紹。
路徑(Path)
路徑(path)是指符合以下約束的表達式:
path
: nodeName ('.' nodeName)*
;
nodeName
: wildcard? identifier wildcard?
| wildcard
;
wildcard
: '*'
| '**'
;我們稱一個路徑中由 '.' 分割的部分叫做路徑結點名(nodeName)。例如:root.a.b.c為一個層級為 4 的路徑。
下面是對路徑結點名(nodeName)的約束:
root作為一個保留字符,它只允許出現在下文提到的時間序列的開頭,若其他層級出現root,則無法解析,提示報錯。- 除了時間序列的開頭的層級(
root)外,其他的層級支持的字符如下:- [ 0-9 a-z A-Z _ ] (字母,數字,下劃線)
- ['\u2E80'..'\u9FFF'] (UNICODE 中文字符)
- 特別地,如果系統在 Windows 系統上部署,那么 database 路徑結點名是大小寫不敏感的。例如,同時創建
root.ln和root.LN是不被允許的。
特殊字符(反引號)
如果需要在路徑結點名中用特殊字符,可以用反引號引用路徑結點名,具體使用方法可以參考反引號。
路徑模式(Path Pattern)
為了使得在表達多個時間序列的時候更加方便快捷,IoTDB 為用戶提供帶通配符*或**的路徑。用戶可以利用兩種通配符構造出期望的路徑模式。通配符可以出現在路徑中的任何層。
*在路徑中表示一層。例如root.vehicle.*.sensor1代表的是以root.vehicle為前綴,以sensor1為后綴,層次等于 4 層的路徑。
**在路徑中表示是(*)+,即為一層或多層*。例如root.vehicle.device1.**代表的是root.vehicle.device1.*, root.vehicle.device1.*.*, root.vehicle.device1.*.*.*等所有以root.vehicle.device1為前綴路徑的大于等于 4 層的路徑;root.vehicle.**.sensor1代表的是以root.vehicle為前綴,以sensor1為后綴,層次大于等于 4 層的路徑。
注意:
*和**不能放在路徑開頭。