Apache IoTDB 系列教程-2:基礎 SQL 操做

今天主要介紹經常使用的 SQL ,包括對元數據和數據的增刪改查,本文的sql都是基於 0.10.0 的,這個大版本立刻發佈!javascript

正文 11018 字(大部分是 sql 和打印信息,漢字很少),預計閱讀時間 10 分鐘。html

目前 IoTDB 的接口主要有 SQL 和 NoSQL 兩種,今天介紹 SQL 接口,爲了方便理解,你們能夠能夠在下面連接下載 0.10.0 預發佈版,一邊看一邊試:java

二進制版下載連接:git

https://pan.baidu.com/s/1KWnEIIE0Duwr9TZVugib6w  github

密碼:dmrgsql

也能夠源代碼編譯:apache

git clone https://github.com/apache/incubator-iotdb.git
cd incubator-iotdb
git fetch origin rel/0.10:rel/0.10
git checkout rel/0.10
mvn clean package -pl distribution -am -DskipTests
二進制發佈包位置:
distribution/target/apache-iotdb-0.10.0-SNAPSHOT-incubating-bin.zip

好,開始!ruby

DDL 數據定義語言ide

參考文檔:函數

http://iotdb.apache.org/UserGuide/Master/Operation%20Manual/DDL%20Data%20Definition%20Language.html

存儲組操做

# 建立存儲組
IoTDB> set storage group to root.turbine


# 查詢存儲組
IoTDB> SHOW STORAGE GROUP
+-------------+
|storage group|
+-------------+
| root.turbine|
+-------------+


# 刪除存儲組
IoTDB> delete storage group root.turbine

建立時間序列

create timeseries root.turbine.d1.s1(temperature1) with datatype=FLOAT, encoding=GORILLA, compression=SNAPPY tags(unit=degree, owner=user1) attributes(description=mysensor1, location=BeiJing)
create timeseries root.turbine.d1.s2(temperature2) with datatype=FLOAT, encoding=GORILLA, compression=SNAPPY tags(unit=degree, owner=user1) attributes(description=mysensor2, location=TianJin)
create timeseries root.turbine.d2.s1(temperature1) with datatype=FLOAT, encoding=GORILLA, compression=SNAPPY tags(unit=degree, owner=user2) attributes(description=mysensor3, location=HeBei)

上邊註冊的序列可視化就是下邊這個圖了(手畫的。。目前沒可視化功能)

爲了實際應用中使用更方便,除了時間序列的路徑和編碼等基本信息外,咱們增長了測點別名、標籤、屬性三個概念。標籤和屬性總大小在配置文件中 tag_attribute_total_size 設置。

別名:測點的別名,能夠和測點名同樣用來讀寫,能夠不設置。

標籤:key=value 形式,能夠經過標籤反向查詢時間序列元數據,好比,單位和擁有者,標籤會常駐內存。目前只能給定一個 tag 查詢條件,可精確查詢和模糊查詢。

屬性:key=value 形式,只能根據時間序列路徑展現出屬性信息,如描述信息和位置。若是沒有反向查詢的需求,建議定義成屬性。

# 插入更新 別名、標籤、屬性
ALTER timeseries root.turbine.d1.s1 UPSERT ALIAS=newAlias TAGS(unit=Degree, owner=me) ATTRIBUTES(description=ha, newAttr=v1)

根據路徑和標籤查詢序列元數據

# 查詢全部時間序列數據
IoTDB> show timeseries
+------------------+------------+-------------+--------+--------+-----------+-----------+--------+-----+------+
|        timeseries|       alias|storage group|dataType|encoding|compression|description|location|owner|  unit|
+------------------+------------+-------------+--------+--------+-----------+-----------+--------+-----+------+
|root.turbine.d1.s1|temperature1| root.turbine|   FLOAT| GORILLA|     SNAPPY|  mysensor1| BeiJing|user1|degree|
|root.turbine.d1.s2|temperature2| root.turbine|   FLOAT| GORILLA|     SNAPPY|  mysensor2| TianJin|user1|degree|
|root.turbine.d2.s1|temperature1| root.turbine|   FLOAT| GORILLA|     SNAPPY|  mysensor3|   HeBei|user2|degree|
+------------------+------------+-------------+--------+--------+-----------+-----------+--------+-----+------+


# 查詢 root.turbine.d1 前綴路徑下的時間序列 
IoTDB> show timeseries root.turbine.d1
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+--------------------------------------------------------+
|        timeseries|       alias|storage group|dataType|encoding|compression|                             tags|                                              attributes|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+--------------------------------------------------------+
|root.turbine.d1.s1|    newAlias| root.turbine|   FLOAT| GORILLA|     SNAPPY|   {"owner":"me","unit":"Degree"}|{"description":"ha","location":"BeiJing","newAttr":"v1"}|
|root.turbine.d1.s2|temperature2| root.turbine|   FLOAT| GORILLA|     SNAPPY|{"owner":"user1","unit":"degree"}|        {"description":"mysensor2","location":"TianJin"}|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+--------------------------------------------------------+


# 根據 tag 精確查詢 owner 爲 user1 的序列
IoTDB> show timeseries root.turbine where owner=user1
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+
|        timeseries|       alias|storage group|dataType|encoding|compression|                             tags|                                      attributes|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+
|root.turbine.d1.s2|temperature2| root.turbine|   FLOAT| GORILLA|     SNAPPY|{"owner":"user1","unit":"degree"}|{"description":"mysensor2","location":"TianJin"}|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+


# 根據 tag 模糊查詢 owner 的 value 中包含 'user' 的序列
IoTDB> show timeseries where owner contains 'user'
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+
|        timeseries|       alias|storage group|dataType|encoding|compression|                             tags|                                      attributes|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+
|root.turbine.d1.s2|temperature2| root.turbine|   FLOAT| GORILLA|     SNAPPY|{"owner":"user1","unit":"degree"}|{"description":"mysensor2","location":"TianJin"}|
|root.turbine.d2.s1|temperature1| root.turbine|   FLOAT| GORILLA|     SNAPPY|{"owner":"user2","unit":"degree"}|  {"description":"mysensor3","location":"HeBei"}|
+------------------+------------+-------------+--------+--------+-----------+---------------------------------+------------------------------------------------+

查看某個路徑的孩子節點

IoTDB> show child paths root.turbine
+---------------+
|    child paths|
+---------------+
|root.turbine.d1|
|root.turbine.d2|
+---------------+

統計時間序列數量

# 統計全部時間序列數量
IoTDB> count timeseries
+-----+
|count|
+-----+
|    3|
+-----+


# 分組統計時間序列,root 爲第 0 層
IoTDB> count timeseries group by level=2
+---------------+-----+
|         column|count|
+---------------+-----+
|root.turbine.d1|    2|
|root.turbine.d2|    1|
+---------------+-----+

查詢全部設備

也就是查詢倒數第二層節點的路徑

IoTDB> show devices
+---------------+
|        devices|
+---------------+
|root.turbine.d1|
|root.turbine.d2|
+---------------+

DML 數據操做語言

參考文檔:

http://iotdb.apache.org/UserGuide/Master/Operation%20Manual/DML%20Data%20Manipulation%20Language.html

數據寫入

一次能夠寫入一個設備、一個時間戳、多個測點的值。

insert into root.turbine.d1(timestamp,s1,s2) values(1,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(2,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(3,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(4,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(5,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(6,1,2);
insert into root.turbine.d1(timestamp,s1,s2) values(10,1,2);

數據刪除

目前只支持刪除一個時間點以前的數據,以後會支持刪除任意一段時間的數據。

delete from root.turbine.d2.s1 where time <= 10

原始數據查詢

接下來就到各類查詢啦,最經常使用的是原始數據查詢。

IoTDB> select s1, s2 from root.turbine.d1
+-----------------------------+------------------+------------------+
|                         Time|root.turbine.d1.s1|root.turbine.d1.s2|
+-----------------------------+------------------+------------------+
|1970-01-01T08:00:00.001+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.002+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.003+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.004+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.005+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.006+08:00|               1.0|               2.0|
|1970-01-01T08:00:00.010+08:00|               1.0|               2.0|
+-----------------------------+------------------+------------------+

單點補空值查詢

傳感器採集的數據不少時間戳有誤差,時間戳精確查詢容易查不到數據,能夠用 previous 或者 linear 方式補空值

IoTDB> select s1 from root.turbine.d1 where time = 8
+----+------------------+
|Time|root.turbine.d1.s1|
+----+------------------+
+----+------------------+


# 用前邊最近的值填過來
IoTDB> select s1 from root.turbine.d1 where time = 8 fill(float[previous])
+-----------------------------+------------------+
|                         Time|root.turbine.d1.s1|
+-----------------------------+------------------+
|1970-01-01T08:00:00.008+08:00|               1.0|
+-----------------------------+------------------+


# 若是想限制補值的範圍,超過這個範圍就不補了,能夠再加個參數,要帶單位
IoTDB> select s1 from root.turbine.d1 where time = 8 fill(float[previous,1ms])
+-----------------------------+------------------+
|                         Time|root.turbine.d1.s1|
+-----------------------------+------------------+
|1970-01-01T08:00:00.008+08:00|              null|
+-----------------------------+------------------+

最新數據查詢

爲了實時的可視化最新數據,咱們單獨作了一個最新數據點查詢功能。用 select last 關鍵字做爲前綴,其餘語法和原始數據同樣,不能加謂詞過濾。

IoTDB> select last * from root
+-----------------------------+------------------+-----+
|                         Time|        timeseries|value|
+-----------------------------+------------------+-----+
|1970-01-01T08:00:00.010+08:00|root.turbine.d1.s1|  1.0|
|1970-01-01T08:00:00.010+08:00|root.turbine.d1.s2|  2.0|
+-----------------------------+------------------+-----+

聚合查詢

統計時間序列的聚合值,咱們目前把各個時間序列都當作獨立的序列看待,聚合也是分序列作。下個版本會加上聚合一個路徑下全部序列的功能。

IoTDB> select count(*) from root where time <= 10
+-------------------------+-------------------------+-------------------------+
|count(root.turbine.d1.s1)|count(root.turbine.d1.s2)|count(root.turbine.d2.s1)|
+-------------------------+-------------------------+-------------------------+
|                        7|                        7|                        0|
+-------------------------+-------------------------+-------------------------+

0.10.0 降頻聚合查詢

降頻聚合0.10的語法和0.9 的不同了。首先介紹 0.10.0 版本的降頻聚合查詢語法,先舉個例子,查一個序列今年5月份天天早上9點到12點的平均值,結果應該相似這樣的:

5月1日 9點-12點:聚合值

5月2日 9點-12點:聚合值

...

5月31日 9點-12點:聚合值

爲了實現這個靈活的查詢,須要一個滑動窗口,窗口從5月1日9點開始,長度是3小時,每次往前滑動24小時,滑到5月31日爲止,每一個窗口內計算一個平均值。

所以咱們主要設計了三個參數:

(1)滑動窗口的起始和終止範圍,左閉右開區間:5月1日到31日

(2)滑動窗口的長度:3小時

(3)滑動步長:24小時

語句以下(我沒寫這麼多數據,目前查出來都是空):

select avg(s1) from root.turbine.d1 group by([2020-05-01T09:00:00, 2020-05-31T12:00:00), 3h, 24h)

再舉一個更簡單的例子:查5月份天天的平均值

這個例子裏,滑動窗口的長度和滑動步長相等,就能夠省掉第三個參數啦:

select avg(s1) from root.turbine.d1 group by([2020-05-01T00:00:00, 2020-06-01T00:00:00), 1d)

0.10.0 採樣補空值

0.10.0 新增的查詢功能,在 group by 查詢的基礎上,若是咱們使用 last_value 聚合函數,就是個採樣功能了,若是某個時間區間沒有值,也可使用前值補空。

# 正常降採樣,沒數據的區間會填充 null
IoTDB> select last_value(s1) from root.turbine.d1 group by([1,10), 2ms)
+-----------------------------+------------------------------+
|                         Time|last_value(root.turbine.d1.s1)|
+-----------------------------+------------------------------+
|1970-01-01T08:00:00.001+08:00|                           1.0|
|1970-01-01T08:00:00.003+08:00|                           1.0|
|1970-01-01T08:00:00.005+08:00|                           1.0|
|1970-01-01T08:00:00.007+08:00|                          null|
|1970-01-01T08:00:00.009+08:00|                          null|
+-----------------------------+------------------------------+


# 降採樣,若是某個區間沒值,能夠用前一個聚合值補空,填充函數爲 previous
IoTDB> select last_value(s1) from root.turbine.d1 group by([1,10), 2ms) fill(float[previous])
+-----------------------------+------------------------------+
|                         Time|last_value(root.turbine.d1.s1)|
+-----------------------------+------------------------------+
|1970-01-01T08:00:00.001+08:00|                           1.0|
|1970-01-01T08:00:00.003+08:00|                           1.0|
|1970-01-01T08:00:00.005+08:00|                           1.0|
|1970-01-01T08:00:00.007+08:00|                           1.0|
|1970-01-01T08:00:00.009+08:00|                           1.0|
+-----------------------------+------------------------------+

此外,還支持另外一種補空值方式,previousuntillast,使用前值補空,直到補到最新點的時間值爲止,就再也不補了,好比這裏最新點時間戳是10,11和13這兩個點就再也不補了。

IoTDB> select last_value(s1) from root.turbine.d1 group by((1,15], 2ms) fill(float[previousuntillast])
+-----------------------------+------------------------------+
|                         Time|last_value(root.turbine.d1.s1)|
+-----------------------------+------------------------------+
|1970-01-01T08:00:00.003+08:00|                           1.0|
|1970-01-01T08:00:00.005+08:00|                           1.0|
|1970-01-01T08:00:00.007+08:00|                           1.0|
|1970-01-01T08:00:00.009+08:00|                           1.0|
|1970-01-01T08:00:00.011+08:00|                           1.0|
|1970-01-01T08:00:00.013+08:00|                          null|
|1970-01-01T08:00:00.015+08:00|                          null|
+-----------------------------+------------------------------+

不知道你們注意到沒,這句話區間是前開後閉,填出來的結果集也是用的閉區間的時間點。這樣就經過 group by fill 語句實現了採樣補空值查詢。

0.9.x 降頻聚合查詢

0.9 老版本的降頻聚合語法和 0.10 的不同。主要有這樣幾個參數

(1)分段間隔,把時間軸按這個長度分紅一段一段的

(2)分割原點,從哪一個點開始分,能夠採用任意一段的端點,默認以 1970年1月1日0點0時0分0秒爲切割原點,也就是時間戳的 0

(3)結果集的展現範圍

前兩個參數固定以後,時間軸的分段就肯定了,以後第三個參數指定結果集。

好比,查詢5月天天的平均值

select avg(s1) from root.turbine.d1 group by (1d, 2020-05-01 00:00:00, [2020-05-01 00:00:00, 2020-05-31 23:59:59]);

按設備對齊查詢

經過上邊的例子咱們能夠看到,IoTDB 查詢的默認表結構是【time,序列1,序列2,...,序列n】,全部序列會按照 time 對齊,若是存在某個序列在一個時間點不存在,會補空值,在作值過濾時候,這種表結構的過濾也會很嚴格。

爲了使得各個設備查詢時不互相影響,咱們支持按 time 和設備對齊查詢,表結構爲【time,設備ID,測點1,測點2,...,測點n】,這種就和關係表結構比較像了,只須要在查詢語句後加 align by device 

IoTDB> select * from root align by device
+-----------------------------+---------------+---+---+
|                         Time|         Device| s1| s2|
+-----------------------------+---------------+---+---+
|1970-01-01T08:00:00.001+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.002+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.003+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.004+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.005+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.006+08:00|root.turbine.d1|1.0|2.0|
|1970-01-01T08:00:00.010+08:00|root.turbine.d1|1.0|2.0|
+-----------------------------+---------------+---+---+

總結

今天的基本操做就先介紹到這,具體的sql 語法能夠參考官網,本文的 sql 能夠粘到 CLI 裏本身玩一玩~ 祝你們週末快樂!

歡迎點在看!讚揚!轉發!