在 IoTDB 中,数据写入遵循以下通用语法:
INSERT INTO <TABLE_NAME> [(COLUMN_NAME[, COLUMN_NAME]*)]? VALUES (COLUMN_VALUE[, COLUMN_VALUE]*)
基本约束包括:
null。now() 进行填充。由于属性一般并不随时间的变化而变化,因此推荐以 update 的方式单独更新属性值,参见下文 数据更新。
在通过 Session 进行数据写入时,IoTDB 支持无模式写入:无需事先手动创建表,系统会根据写入请求中的信息自动构建表结构,之后直接执行数据写入操作。
示例:
try (ITableSession session = new TableSessionBuilder() .nodeUrls(Collections.singletonList("127.0.0.1:6667")) .username("root") .password("root") .build()) { session.executeNonQueryStatement("CREATE DATABASE db1"); session.executeNonQueryStatement("use db1"); // 不创建表直接写入数据 List<String> columnNameList = Arrays.asList("region_id", "plant_id", "device_id", "model", "temperature", "humidity"); List<TSDataType> dataTypeList = Arrays.asList( TSDataType.STRING, TSDataType.STRING, TSDataType.STRING, TSDataType.STRING, TSDataType.FLOAT, TSDataType.DOUBLE); List<ColumnCategory> columnTypeList = new ArrayList<>( Arrays.asList( ColumnCategory.TAG, ColumnCategory.TAG, ColumnCategory.TAG, ColumnCategory.ATTRIBUTE, ColumnCategory.FIELD, ColumnCategory.FIELD)); Tablet tablet = new Tablet("table1", columnNameList, dataTypeList, columnTypeList, 100); for (long timestamp = 0; timestamp < 100; timestamp++) { int rowIndex = tablet.getRowSize(); tablet.addTimestamp(rowIndex, timestamp); tablet.addValue("region_id", rowIndex, "1"); tablet.addValue("plant_id", rowIndex, "5"); tablet.addValue("device_id", rowIndex, "3"); tablet.addValue("model", rowIndex, "A"); tablet.addValue("temperature", rowIndex, 37.6F); tablet.addValue("humidity", rowIndex, 111.1); if (tablet.getRowSize() == tablet.getMaxRowNumber()) { session.insert(tablet); tablet.reset(); } } if (tablet.getRowSize() != 0) { session.insert(tablet); tablet.reset(); } }
在代码执行完成后,可以通过下述语句确认表已成功创建,其中包含了时间列、标签列、属性列以及测点列等各类信息。
IoTDB> desc table1 +-----------+---------+-----------+ | ColumnName| DataType| Category| +-----------+---------+-----------+ | time|TIMESTAMP| TIME| | region_id| STRING| TAG| | plant_id| STRING| TAG| | device_id| STRING| TAG| | model| STRING| ATTRIBUTE| |temperature| FLOAT| FIELD| | humidity| DOUBLE| FIELD| +-----------+---------+-----------+
在写入操作中,可以指定部分列,未指定的列将不会被写入任何内容(即设置为 null)。
示例:
INSERT INTO table1(region, plant_id, device_id, time, temperature, humidity) VALUES ('北京', '1001', '100', '2025-11-26 13:37:00', 90.0, 35.1) INSERT INTO table1(region, plant_id, device_id, time, temperature) VALUES ('北京', '1001', '100', '2025-11-26 13:38:00', 91.0)
标签列、属性列和测点列可以指定空值(null),表示不写入任何内容。
示例(与上述事例等价):
# 上述部分列写入等价于如下的带空值写入 INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity) VALUES ('北京', '1001', '100', null, null, '2025-11-26 13:37:00', 90.0, 35.1) INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity) VALUES ('北京', '1001', '100', null, null, '2025-11-26 13:38:00', 91.0, null)
当向不包含任何标签列的表中写入数据时,系统将默认创建一个所有标签列值均为 null 的device。
注意,该操作不仅会自动为表中已有的标签列填充 null 值,而且对于未来新增的标签列,同样会自动填充 null。
支持同时写入多行数据,提高数据写入效率。
示例:
INSERT INTO table1 VALUES ('2025-11-26 13:37:00', '北京', '1001', '100', 'A', '180', 90.0, 35.1, true, '2025-11-26 13:37:34'), ('2025-11-26 13:38:00', '北京', '1001', '100', 'A', '180', 90.0, 35.1, true, '2025-11-26 13:38:25') INSERT INTO table1 (region, plant_id, device_id, model_id, maintenance, time, temperature, humidity, status, arrival_time) VALUES ('北京', '1001', '100', 'A', '180', '2025-11-26 13:37:00', 90.0, 35.1, true, '2025-11-26 13:37:34'), ('北京', '1001', '100', 'A', '180', '2025-11-26 13:38:00', 90.0, 35.1, true, '2025-11-26 13:38:25')
COLUMN_NOT_EXIST(616)。DATA_TYPE_MISMATCH(507)。IoTDB 表模型支持追加查询写回功能,即INSERT INTO QUERY 语句,支持将查询结果写入已经存在的表中。
注意:该功能从 V 2.0.6 版本开始提供。
INSERT INTO table_name [ ( column [, ... ] ) ] query
其中 query 支持三种形式,下面将通过示例进行说明。
以示例数据为源数据,先创建目标表
IoTDB:database1> CREATE TABLE target_table ( time TIMESTAMP TIME, region STRING TAG, device_id STRING TAG, temperature FLOAT FIELD ); Msg: The statement is executed successfully.
即 query 处为直接通过select ... from ...执行的查询。
例如:使用标准查询语句,将 table1 中北京地区的 time, region, device_id, temperature 数据查询写回到 target_table 中
IoTDB:database1> insert into target_table select time,region,device_id,temperature from table1 where region = '北京' Msg: The statement is executed successfully. IoTDB:database1> select * from target_table where region='北京' +-----------------------------+------+---------+-----------+ | time|region|device_id|temperature| +-----------------------------+------+---------+-----------+ |2024-11-26T13:37:00.000+08:00| 北京| 100| 90.0| |2024-11-26T13:38:00.000+08:00| 北京| 100| 90.0| |2024-11-27T16:38:00.000+08:00| 北京| 101| null| |2024-11-27T16:39:00.000+08:00| 北京| 101| 85.0| |2024-11-27T16:40:00.000+08:00| 北京| 101| 85.0| |2024-11-27T16:41:00.000+08:00| 北京| 101| 85.0| |2024-11-27T16:42:00.000+08:00| 北京| 101| null| |2024-11-27T16:43:00.000+08:00| 北京| 101| null| |2024-11-27T16:44:00.000+08:00| 北京| 101| null| +-----------------------------+------+---------+-----------+ Total line number = 9 It costs 0.029s
即 query 处为表引用方式table source_table。
例如:使用表引用查询,将 table3 中的数据查询写回到 target_table 中
IoTDB:database1> insert into target_table(time,device_id,temperature) table table3 Msg: The statement is executed successfully. IoTDB:database1> select * from target_table where region is null +-----------------------------+------+---------+-----------+ | time|region|device_id|temperature| +-----------------------------+------+---------+-----------+ |2025-05-13T00:00:00.001+08:00| null| d1| 90.0| |2025-05-13T00:00:01.002+08:00| null| d1| 85.0| |2025-05-13T00:00:02.101+08:00| null| d1| 85.0| |2025-05-13T00:00:03.201+08:00| null| d1| null| |2025-05-13T00:00:04.105+08:00| null| d1| 90.0| |2025-05-13T00:00:05.023+08:00| null| d1| 85.0| |2025-05-13T00:00:06.129+08:00| null| d1| 90.0| +-----------------------------+------+---------+-----------+ Total line number = 7 It costs 0.015s
即 query 处为带括号的子查询。
例如:使用子查询,将 table1 中时间与 table2 上海地区记录匹配的数据的 time, region, device_id, temperature 查询写回到 target_table
IoTDB:database1> insert into target_table (select t1.time, t1.region as region, t1.device_id as device_id, t1.temperature as temperature from table1 t1 where t1.time in (select t2.time from table2 t2 where t2.region = '上海')) Msg: The statement is executed successfully. IoTDB:database1> select * from target_table where region = '上海' +-----------------------------+------+---------+-----------+ | time|region|device_id|temperature| +-----------------------------+------+---------+-----------+ |2024-11-28T08:00:00.000+08:00| 上海| 100| 85.0| |2024-11-29T11:00:00.000+08:00| 上海| 100| null| +-----------------------------+------+---------+-----------+ Total line number = 2 It costs 0.014s
INSERT INTO testtb SELECT * FROM testtb。550: Table 'xxx.xxx' does not exist。701: Insert query has mismatched column types。701: time column can not be null701: No Field column presentINSERT INTO QUERY。INSERT INTO QUERY。INSERT INTO QUERY不支持 Explain 和 Explain Analyze。SELECT 权限。WRITE权限。UPDATE <TABLE_NAME> SET updateAssignment (',' updateAssignment)* (WHERE where=booleanExpression)? updateAssignment : identifier EQ expression ;
update语句仅允许修改属性(ATTRIBUTE)列的值。WHERE 的规则:insert语句来实现指定行的更新。示例:
update table1 set b = a where substring(a, 1, 1) like '%'