IoTDB簡介
1. 引言
在本教程中,我們將了解 Apache IoTDB 資料庫。我們將了解它是什麼,如何使用它以及我們可以用它做什麼。
2. 什麼是 IoTDB
IoTDB 是一個免費的開源資料庫,專為儲存時間序列資料而設計。它主要面向物聯網設備,但也可用於儲存任何以時間戳記標識的指標序列或記錄。此外,它還與 SQL 相容,因此更容易整合到我們的應用程式中。
由於 IoTDB 的設計初衷就是為了服務物聯網設備,因此其儲存結構也體現了這一點。我們的資料庫、時間序列和資料欄位通常採用樹狀結構進行建模,這反映了我們記錄來自不同設備、類型各異的不同資料。
例如,我們可能需要記錄渦輪機轉速隨時間的變化。我們可以將此記錄到時間序列root.baeldung.turbine.device1.speed.具體來說:
-
root.baeldung– 我們的資料庫 -
turbine.device1 –我們的設備 -
speed-我們想要記錄的數據
如果我們需要記錄多個設備的相同數據,只需建立多個時間序列進行記錄即可。
3. 運行 IoTDB
IoTDB 由三種不同的服務組成,可以一起使用:
- 配置節點
- 資料節點
- (可選)人工智慧節點
我們可以以獨立模式運行此程序,其中只有一個進程,該進程包含一個配置節點和一個資料節點。或者,我們也可以將其運行在高可用性叢集中。在這種情況下,我們需要運行 3 個配置節點和至少 3 個資料節點,當然,我們可以根據需要添加更多節點。這確保了即使某個節點發生故障,我們也能繼續運作。
此外,我們還可以運行 AI 節點,這些節點提供一些 AI 模型,我們可以利用這些模型即時處理我們的資料。
使用 Docker 是上手 IoTDB 最簡單的方法。 Apache 提供了一些用於各種配置的Docker Compose 入門檔案。本文將使用docker-compose-standalone.yml檔案。
此檔案假設我們已經為容器建立了一個 Docker 網路橋接器:
$ docker network create --driver=bridge --subnet=172.18.0.0/16 --gateway=172.18.0.1 iotdb
ca767e800f66e4b067a6952420c784392661fd0aa21318e3ce3dc53fdad4ab00
然後我們就可以啟動容器了:
$ docker compose up
[+] Running 1/1
✔ Container iotdb-service Created 0.0s
Attaching to iotdb-service
.....
iotdb-service | 2025-12-28 10:16:48,541 [main] INFO oaidb.service.DataNode:261
- Congratulations, IoTDB DataNode is set up successfully. Now, enjoy yourself!
iotdb-service | 2025-12-28 10:16:48,542 [main] INFO oaidb.service.DataNode:288
- DataNode started
iotdb-service | 2025-12-28 10:16:51,080 [pool-36-IoTDB-DataNodeInternalRPC-Processor-1]
INFO oaidqpClusterTopology:152 - [Topology] latest view from config-node: {1=[1]}
至此,我們的資料庫已運行並可供使用。
4. 連接到 IoTDB
現在我們的資料庫已經運行,我們需要能夠連接到它。
4.1 命令列介面
為了管理我們的資料庫,IoTDB 包含一個用於連接的命令列介面。該介面也安裝在 Docker 容器內,因此我們可以使用 Docker 輕鬆運行它:
$ docker exec -it iotdb-service start-cli.sh
---------------------
Starting IoTDB Cli
---------------------
_____ _________ ______ ______
|_ _| | _ _ ||_ _ `.|_ _ \
| | .--.|_/ | | \_| | | `. \ | |_) |
| | / .'`\ \ | | | | | | | __'.
_| |_| \__. | _| |_ _| |_.' /_| |__) |
|_____|'.__.' |_____| |______.'|_______/ version 2.0.5 (Build: 0917050)
Successfully login at 127.0.0.1:6667
IoTDB>
這為我們提供了一個類似 Postgres 的psql指令的命令列介面。
4.2. JDBC 驅動程式
IoTDB也為不同的程式語言提供了多種驅動程式。其中包括JDBC驅動程序,使我們能夠從Java連接到資料庫。
要使用此功能,我們首先需要將驅動程式新增至專案。如果使用 Maven,我們可以將此依賴項新增至pom.xml檔案:
<dependencies>
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-jdbc</artifactId>
<version>2.0.5</version>
</dependency>
</dependencies>
完成這些步驟後,我們就可以像使用其他任何 JDBC 驅動程式一樣使用它:
Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
try (Connection con = DriverManager
.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root")) {
// use conn here
}
由於這些是標準的 JDBC 驅動程序,我們可以將它們與任何相容的東西一起使用——例如 Spring JdbcTemplate 。
5. 資料庫管理
在 IoTDB 中,我們所有的資料都儲存在資料庫中。這些資料庫的工作方式與其他資料庫管理系統類似,由一系列時間序列組成,每個時間序列都包含相應的資料。
我們使用CREATE DATABASE命令建立一個新資料庫:
IoTDB> CREATE DATABASE root.baeldung;
Msg: The statement is executed successfully.
我們可以使用SHOW DATABASES指令查看存在的資料庫:
IoTDB> SHOW DATABASES;
+-------------+-----------------------+---------------------+-------------------+---------------------+
| Database|SchemaReplicationFactor|DataReplicationFactor|TimePartitionOrigin|TimePartitionInterval|
+-------------+-----------------------+---------------------+-------------------+---------------------+
|root.baeldung| 1| 1| 0| 604800000|
+-------------+-----------------------+---------------------+-------------------+---------------------+
Total line number = 1
It costs 0.107s
我們也可以使用DELETE DATABASE命令刪除整個資料庫:
IoTDB> DELETE DATABASE root.baeldung;
Msg: The statement is executed successfully.
請注意,這是不可逆的,所以我們需要小心謹慎,確保操作正確。
6. 時間序列管理
然後,我們在資料庫中將資料收集起來,形成一個時間序列。這與傳統 SQL 資料庫中的表格大致類似。
一個簡單的時間序列包含一個時間戳記和一個值,該值可以是任何合適的類型。我們在產生時間序列資料的同時,將其記錄下來。
我們可以使用CREATE TIMESERIES指令來建立時間序列:
IoTDB> CREATE TIMESERIES root.baeldung.turbine.device1.speed FLOAT;
Msg: The statement is executed successfully.
或者,我們可以建立對齊時間序列。這是一種特殊情況,其中有多個不同的測量值,它們都與同一輸入相關,並且都在同一時刻進行。因此,我們希望能夠更輕鬆地將這些測量值關聯起來。我們可以使用CREATE ALIGNED TIMESERIES指令來建立這些時間序列:
IoTDB> CREATE ALIGNED TIMESERIES root.baeldung.car.device2(lat FLOAT, lng FLOAT);
Msg: The statement is executed successfully.
然後,我們可以使用SHOW TIMESERIES指令來查看我們所建立的所有時間序列:
`IoTDB> SHOW TIMESERIES;
+-----------------------------------+-----+-------------+--------+--------+-----------+----+----------+--------+------------------+--------+
| Timeseries|Alias| Database|DataType|Encoding|Compression|Tags|Attributes|Deadband|DeadbandParameters|ViewType|
+-----------------------------------+-----+-------------+--------+--------+-----------+----+----------+--------+------------------+--------+
|root.baeldung.turbine.device1.speed| null|root.baeldung| FLOAT| GORILLA| LZ4|null| null| null| null| BASE|
| root.baeldung.car.device2.lng| null|root.baeldung| FLOAT| GORILLA| LZ4|null| null| null| null| BASE|
| root.baeldung.car.device2.lat| null|root.baeldung| FLOAT| GORILLA| LZ4|null| null| null| null| BASE|
+-----------------------------------+-----+-------------+--------+--------+-----------+----+----------+--------+------------------+--------+
Total line number = 3
It costs 0.083s`
在這裡我們會看到,對齊後的時間序列實際上顯示為單獨的欄位。它們就是這樣儲存的,但由於我們在創建它們時是對齊的,所以我們可以將它們視為一個整體來操作其中的資料。
我們也可以使用DELETE TIMESERIES指令刪除時間序列:
IoTDB> DELETE TIMESERIES root.baeldung.turbine.device1.speed;
Msg: The statement is executed successfully.
請注意,如果要刪除已對齊的時間序列,則需要逐一刪除每個字段,不能一次刪除整個資料集。
7. 數據管理
現在我們已經有了資料庫以及其中的一些時間序列數據,接下來需要在其中添加一些數據。與傳統的 SQL 資料庫類似,我們可以插入、查詢和刪除記錄。但是,我們無法直接更新現有記錄。
7.1 插入數據
我們使用INSERT INTO命令插入資料:
try (PreparedStatement stmt = con.prepareStatement("INSERT INTO root.baeldung.turbine.device1(timestamp, speed) VALUES (?, ?)")) {
stmt.setObject(1, Instant.now().toEpochMilli());
stmt.setObject(2, 10);
stmt.executeUpdate();
}
此處提供的時間戳為自紀元以來的毫秒數。
或者,我們可以從語句中省略時間戳:
try (PreparedStatement stmt = con.prepareStatement("INSERT INTO root.baeldung.turbine.device1(speed) VALUES (?)")) {
stmt.setObject(1, 20);
stmt.executeUpdate();
}
如果我們這樣做,IoTDB 將使用當前時間而不是我們提供的值。
如果我們處理的是對齊的時間序列,我們可以用一條語句將資料插入所有欄位中:
try (PreparedStatement stmt = con.prepareStatement("INSERT INTO root.baeldung.car.device2(lat, lng) VALUES (?, ?)")) {
stmt.setObject(1, 40.6892);
stmt.setObject(2, 74.0445);
stmt.executeUpdate();
}
這樣做有助於確保所有對齊欄位的資料始終使用相同的時間戳記。當 IoTDB 為我們提供當前時間時,這一點尤其有用。
7.2 資料查詢
將資料新增至時間序列後,我們需要能夠查詢它。我們使用SELECT語句來實現這一點,方法與傳統 SQL 資料庫相同:
try (PreparedStatement stmt = con.prepareStatement("SELECT * FROM root.baeldung.turbine.device1")) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
long timestamp = rs.getLong(1);
float speed = rs.getFloat(2);
// Do something with the data
}
}
}
這與任何 SQL 資料庫的工作方式相同,允許我們指定要查詢的時間序列、要傳回的欄位以及要套用於傳回資料的任何條件:
try (PreparedStatement stmt = con.prepareStatement("SELECT lat FROM root.baeldung.car.device2 WHERE timestamp = ?")) {
stmt.setObject(1, Instant.now().toEpochMilli());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
long timestamp = rs.getLong(1);
float lat = rs.getFloat(2);
// Do something with the data
}
}
}
請注意,即使我們沒有請求時間戳,記錄也總是會傳回時間戳記。因此,限制傳回的欄位僅在查詢具有多個資料欄位的對齊時間序列時才有用。
8. 總結
本文簡要介紹了 IoTDB 時間序列資料庫。這個系統還有更多功能。下次需要處理來自物聯網設備的資料來源時,不妨試試它。
與往常一樣,本文中的所有範例都可以在 GitHub 上找到。