写点什么

IoTDB 可实现的基本操作 —— 数据写入、删除、导出、元数据管理、时区设置 | 小白教程文档(四)

作者:Apache IoTDB
  • 2023-01-18
    北京
  • 本文字数:9321 字

    阅读完需:约 31 分钟

IoTDB 可实现的基本操作 —— 数据写入、删除、导出、元数据管理、时区设置 | 小白教程文档(四)

前言


上篇教程介绍了 Apache IoTDB 处理时序数据时,能够实现的部分具体功能和具体的操作命令,包括数据导入、基本查询、和聚合查询。


本篇将继续介绍 Apache IoTDB 可实现的其他功能和相关 SQL 语句命令,包括数据的写入、删除、导出、元数据操作和时区设置的注意事项。

1. 数据写入、删除与导出

1.1 插入数据


物联网场景下,元件产生数据将自动写入,但有时候,如果过去的一些数据需要修改,可以使用 insert 语句插入修改后的值,覆盖原数据。


例如,我们可以向已有的时间序列 root.BHSFC.Q1.W002.speed 中插入单行数据,SQL 语句如下:


insert into root.BHSFC.Q1.W003(timestamp,speed) values(1657472400000,2)


我们可以使用查询语句查看是否插入成功:


select speed from root.BHSFC.Q1.W003


显示结果如下,可知已插入成功:


IoTDB> select speed from root.BHSFC.Q1.W003+-----------------------------+------------------------+| Time|root.BHSFC.Q1.W003.speed|+-----------------------------+------------------------+|2022-07-11T00:00:00.000+08:00| 1.0||2022-07-11T01:00:00.000+08:00| 2.0|+-----------------------------+------------------------+Total line number = 2

1.2 删除数据

1.2.1 SQL 语句删除

1.2.1.1 删除整个时间序列


我们可以使用 SQL 语句删除单个时间序列,例如以下的 SQL 语句:


delete from root.BHSFC.Q1.W003.speed


我们可以验证一下,输入查询语句 select speed from root.BHSFC.Q1.W003 ,输出结果已经没有数据了,说明删除成功了:


IoTDB> select speed from root.BHSFC.Q1.W003+----+------------------------------+|Time|root.BHSFC.Q1.W003.speed|+----+------------------------------++----+------------------------------+Empty set.
复制代码


1.2.1.2 删除时间范围内的数据


也可以与 where 语句结合删除某个时间片段,如删除 2022 年 1 月 14 日零点之后的数据:


delete from root.BHSFC.Q1.W003 where time<=2022-01-14T00:00:00


1.2.2 TTL 自动删除


TTL 是数据存活时间,将针对存储组进行运作。设置 TTL 后 Apache IoTDB 将自动删除此时间之前的数据,设置完毕即刻生效。


1.2.2.1 设置 TTL


设置 TTL 的 SQL 语句为:


set ttl to root.BHSFC.Q1.W003 3600000


这条语句表示在 root.BHSFCQ1.W003 设备中,最近一个小时的数据将会保存,旧数据会被删除。


1.2.2.2 取消 TTL


我们也可以取消这条时间序列的 TTL ,SQL 语句为:


unset ttl to root.BHSFC.Q1.W003


1.2.2.3 显示 TTL


我们还可以查询目前已设置的 TTL ,SQL 语句为:


show all ttl


输出的结果为:


+-------------+----+|storage group| ttl|+-------------+----+| root.ln|null|| root.BHSFC|null|+-------------+----+Total line number = 2


未设置 TTL 的存储组的 TTL 将显示为 null。

1.3 导出数据


我们可以使用 CSV 工具将数据导出。首先进入 tools 目录,然后输入 SQL 语句:


./export-csv.sh -h 127.0.0.1 -p 6667 -u root -pw root -td ./


之后会出现提示输入查询语句,我们按需输入 SQL 语句即可。例如我们要导出测试数据的平均值,则输入:


select AVG(*) from root.BHSFC.Q1.W002


结果显示如下:


ExportCsv> please input query: select AVG() from root.BHSFC.Q1.W002select AVG() from root.BHSFC.Q1.W00219:23:27.053 [main] DEBUG org.apache.iotdb.session.Session - EndPoint(ip:127.0.0.1, port:6667) execute sql select AVG(*) from root.BHSFC.Q1.W002Export completely!


成功导出了一个 CSV 表格,内容为:


AVG(root.BHSFC.Q1.W002.WROT_HubTmp)17.683083226110213


至此,结合上篇我们完整的了解了 IoTDB 在数据写入、导入、修改、查询、导出周期的基本操作实现和命令语句设置。但除此之外,还有一部分操作非常重要,了解它们将会让我们对 IoTDB 的整体数据结构能实现的功能有更好的了解,这就是元数据管理。


2. 元数据管理


元数据是关于数据的组织、数据域及其关系的信息。元数据管理将使我们对 IoTDB 存入数据的源、目标、转换规则等有更加深入的了解,和管理调整的能力。


下面将从 5 个部分来阐释 IoTDB 中涉及的元数据管理:TsFile 管理、存储组管理、时间序列管理、元数据模板管理和节点管理。

2.1 TsFile 管理


TsFile 是 Apache IoTDB 自研的列式存储文件格式。我们可利用已有的 TsFile 文件来体验其管理操作。


首先我们进入 IoTDB 的 data 文件夹,一路点进去能找到 TsFile 后缀的文件,和以 TsFlie.resource 为后缀的文件,我们只复制那一个 TsFile 后缀的文件到其他文件夹即可,然后就可以进行下面的删除操作,最后再对复制过去的 TsFile 进行下面的加载操作。

2.1.1 删除 TsFile


我们可以使用 remove '<path>' 语句来删除 TsFile 文件,例如我们要删除 /usr/apache-iotdb-0.13.0-all-bin/data/data/sequence/root.BHSFC/0/0/ 文件夹下的 1657277482259-1-0-2.tsfile 文件,则指令为:


remove '/usr/apache-iotdb-0.13.0-all-bin/data/data/sequence/root.BHSFC/0/0/1657277482259-1-0-2.tsfile'


提示 executed successfully 即为删除成功,我们可以查询一下行数,发现变为 0 了:


IoTDB> select count(WROT_HubTmp) from root.BHSFC.Q1.W002+-------------------------------------+|count(root.BHSFC.Q1.W002.WROT_HubTmp)|+-------------------------------------+| 0|+-------------------------------------+Total line number = 1

2.1.2 加载 TsFile


加载 TsFile 文件的指令为:


load '<path/dir>' [autoregister=true/false][,sglevel=int][,verify=true/false]


这里的路径可以是文件路径也可以是文件夹路径,可以导入单个文件或者导入文件夹。autoregister 表示是否自动创建 schema ,参数为 true 表示自动创建 schema,相反 false 表示不创建,默认为 true;sglevel 表示设定存储组级别,默认为 iotdb-datanode.properties 中设置的级别;verify 表示是否对 TsFile 中的时间序列进行元数据检查,默认为 true。开启检查时如果载入的 TsFile 中的时间序列在当前 IoTDB 中也存在,则会比较该时间序列的所有 Measurement 的数据类型是否一致,如果出现不一致将会导致载入失败,关闭该选项会跳过检查,载入更快。


我们输入如下,此前已将 TsFile 文件复制到了文件夹 /var/opt/ 下:


load '/var/opt/1657277482259-1-0-2.tsfile' autoregister=false,sglevel=1,verify=true


输入之后显示 executed successfully 则为加载成功,可以查询一下行数来验证是否已经导入成功,发现行数由 0 变为 13834 了:


IoTDB> load '/var/opt/1657277482259-1-0-2.tsfile' autoregister=false,sglevel=1,verify=trueMsg: The statement is executed successfully.IoTDB> select count(WROT_HubTmp) from root.BHSFC.Q1.W002+-------------------------------------+|count(root.BHSFC.Q1.W002.WROT_HubTmp)|+-------------------------------------+| 13834|+-------------------------------------+Total line number = 1

2.2 存储组管理

2.2.1 创建存储组


根据存储模型创建数据模型,我们可以使用 CREATE STORAGE GROUP 语句,例如创建一个名为 root.ln 的存储组:


create storage group root.ln


提示 “The statement is executed successfully” 即为创建成功:


IoTDB> create storage group root.lnMsg: The statement is executed successfully.

2.2.2 查看存储组


我们可以使用 show storage group 语句查看存储组,SQL 语句如下:


show storage group


使用 show storage group 查看所有存储组,输出的结果如下:


IoTDB> show storage group+-------------+|storage group|+-------------+| root.BHSFC|+-------------+Total line number = 1


同样也可以使用通配符简化查询,如 show storage group root.** 。

2.2.3 删除存储组


我们可以使用 delete storage group 语句删除存储组,如删除存储组 roo.BHSFC 的 SQL 语句为:


delete storage group root.BHSFC


同样我们可以使用通配符 * 简化语句。

2.2.4 统计存储组数量


我们可以使用 count storage group 语句统计存储组数量,统计所有存储组的 SQL 语句为:


count storage group


输出结果为:


IoTDB> count storage group+-------------+|storage group|+-------------+| 1|+-------------+Total line number = 1


同样我们可以使用通配符 * 简化语句。

2.3 时间序列管理

2.3.1 创建对齐时间序列


前面我们创建了单条时间序列 root.BHSFC.Q1.W003.speed。现在我们来创建对齐时间序列。对齐指的是不同传感器的值同时到来,即时间序列可以按一列时间戳来存储,例如我们看之前的数据模式图,设备 w002 和 w003 分属两个实体,它们之下的两条时间序列是非对齐的,即存储的时间戳和时间间隔可以不一致。而设备 wf01 下有两个传感器,status 和 temperature 可以设置为对齐时间序列。


我们可以输入以下 SQL 语句创建对齐时间序列:


create aligned timeseries root.ln.wf01(status BOOLEAN encoding=PLAIN compressor=SNAPPY, temperature FLOAT encoding=PLAIN compressor=SNAPPY)

2.3.2 查询时间序列


我们可以使用 show timeseries <Path> 来查询时间序列。例如查询所有时间序列的 SQL 语句为:


show timeseries


输出结果为:


IoTDB> show timeseries+------------------------------+-----+-------------+--------+--------+-----------+----+----------+| timeseries|alias|storage group|dataType|encoding|compression|tags|attributes|+------------------------------+-----+-------------+--------+--------+-----------+----+----------+| root.ln.wf01.temperature| null| root.ln| FLOAT| PLAIN| SNAPPY|null| null|| root.ln.wf01.status| null| root.ln| BOOLEAN| PLAIN| SNAPPY|null| null||root.BHSFC.Q1.W002.WROT_HubTmp| null| root.BHSFC| DOUBLE| GORILLA| SNAPPY|null| null|| root.BHSFC.Q1.W003.speed| null| root.BHSFC| FLOAT| RLE| SNAPPY|null| null|+------------------------------+-----+-------------+--------+--------+-----------+----+----------+Total line number = 4


查询存储组 root.BHSFC 下的时间序列,SQL 语句为:


show timeseries root.BHSFC.**


输出结果为:


IoTDB> show timeseries root.BHSFC.**+------------------------------+-----+-------------+--------+--------+---------- -+----+----------+| timeseries|alias|storage group|dataType|encoding|compressio n|tags|attributes|+------------------------------+-----+-------------+--------+--------+---------- -+----+----------+|root.BHSFC.Q1.W002.WROT_HubTmp| null| root.BHSFC| DOUBLE| GORILLA| SNAPP Y|null| null|| root.BHSFC.Q1.W003.speed| null| root.BHSFC| FLOAT| RLE| SNAPP Y|null| null|+------------------------------+-----+-------------+--------+--------+---------- -+----+----------+Total line number = 2

2.3.3 删除时间序列


我们可以使用 DELETE TimeSeries <PathPattern> 语句来删除时间序列,例如删除时间序列 root.ln.wf01.temperature 的 SQL 语句如下:


delete timeseries root.ln.wf01.temperature


2.3.4 统计时间序列总数


我们可以使用 COUNT TIMESERIES<Path> 来统计一条路径中的时间序列个数。例如统计所有的时间序列,SQL 语句为:


count timeseries root.**


显示结果为:


IoTDB> count timeseries root.**+-----+|count|+-----+| 3|+-----+Total line number = 1


2.4 元数据模板管理


元数据模板可以简化同类型实体的管理,减少元数据内存占用。

2.4.1 创建元数据模板


根据需要可以创建不同的元数据模板,例如有两个对齐的时间序列,那么可创建包含一组对齐序列的元数据模板,SQL 语句为:


create schema template t1 aligned (1 FLOAT encoding=Gorilla, 2 FLOAT encoding=Gorilla)

2.4.2 挂载元数据模板


创建之后需挂载元数据模板进行使用,这里我们选择把它应用到 root.ln 存储组的下一层级,SQL 语句为:


set schema template t1 to root.ln.wf01


此时这个模板是空的,虽然这个存储组下有两条之前创建的时间序列,但它们不会挂载到新创建的元数据模板。我们重新创建时间序列,SQL 语句为:


create timeseries of schema template on root.ln.wf01.test


这样两条共享 root.ln.wf01.test 路径的时间序列就创建好了,我们简单查询一下时间序列:


show timeseries root.ln.**


查询结果显示:


IoTDB> show timeseries root.ln.**+------------------------+-----+-------------+--------+--------+-----------+----+----------+| timeseries|alias|storage group|dataType|encoding|compression|tags|attributes|+------------------------+-----+-------------+--------+--------+-----------+----+----------+| root.ln.wf01.test.1| null| root.ln| FLOAT| GORILLA| SNAPPY|null| null|| root.ln.wf01.test.2| null| root.ln| FLOAT| GORILLA| SNAPPY|null| null||root.ln.wf01.temperature| null| root.ln| FLOAT| GORILLA| SNAPPY|null| null|| root.ln.wf01.status| null| root.ln| FLOAT| GORILLA| SNAPPY|null| null|+------------------------+-----+-------------+--------+--------+-----------+----+----------+Total line number = 4


可以看到两条时间序列 root.ln.wf01.test.1 和 root.ln.wf01.test.2 已经创建好了。


我们检查一下是否对齐:


show devices root.ln.wf01.**


查询结果为:


IoTDB> show devices root.ln.wf01.**+-----------------+---------+| devices|isAligned|+-----------------+---------+|root.ln.wf01.test| true|+-----------------+---------+Total line number = 1

2.4.3 查看元数据模板


查看所有元数据模板,SQL 语句为:


show schema templates


查询结果为:


IoTDB> show schema templates+-------------+|template name|+-------------+| t1|+-------------+Total line number = 1


查看某个元数据模板下的物理量,SQL 语句为:


show nodes in schema template t1


查询结果为:


IoTDB> show nodes in schema template t1+-----------+--------+--------+-----------+|child nodes|dataType|encoding|compression|+-----------+--------+--------+-----------+| 1| FLOAT| GORILLA| SNAPPY|| 2| FLOAT| GORILLA| SNAPPY|+-----------+--------+--------+-----------+

2.4.4 卸载/删除元数据模板


卸载元数据模板,SQL 语句为:


unset schema template t1 from root.ln.wf01


此场景输入会报错,说模板正在应用:


IoTDB> unset schema template t1 from root.ln.wf01Msg: 326: Template is in use on root.ln.wf01.test


因此我们需要先解除元数据模板的应用才能卸载,SQL 语句为:


deactivate schema template t1 from root.ln.wf01.test


这时候再卸载就成功了。


最后我们删除这个元数据模板,SQL 语句为:


drop schema template t1

2.5 节点管理

2.5.1 查看子路径


我们可以使用 SHOW CHILD PATHS pathPattern 来查看此路径模式所匹配的路径的下一层的所有路径,例如查看 root.BHSFC 的下一层:


show child paths root.BHSFC


输出为:


IoTDB> show child paths root.BHSFC+-------------+| child paths|+-------------+|root.BHSFC.Q1|+-------------+Total line number = 1

2.5.2 查看子节点


我们可以使用 SHOW CHILD NODES pathPattern 查看此路径模式所匹配的节点的下一层的所有节点,例如查询 root 的下一层:


show child nodes root


输出为:


IoTDB> show child nodes root+-----------+|child nodes|+-----------+| BHSFC|| ln|+-----------+Total line number = 2

2.5.3 统计节点数


我们可以使用 COUNT NODES <PathPattern> LEVEL=<INTEGER> 来统计当前满足某路径模式的路径中指定层级的节点个数。


结合上图的数据模式,假如我们想统计 root.BHSFC 存储组中的节点数,则 SQL 语句为:


count nodes root.BHSFC.Q1.* level=3


输出结果为:


IoTDB> count nodes root.BHSFC.Q1.* level=3+-----+|count|+-----+| 2|+-----+Total line number = 1


两个节点即 level 3 上 Q1 的两个分支 w002 和 w003。


下面这条 SQL 语句,则表示统计层级为 3,即路径 ln 之下所有的节点数:


count nodes root.ln.** level=3


结合数据模式图可看到应为 Wf01、status 和 temperature 共 3 个。输出结果为:


IoTDB> count nodes root.ln.** level=3+-----+|count|+-----+| 3|+-----+Total line number = 1


至此,我们对于 IoTDB 可以实现的基本功能已经有了全面的了解。本教程的最后一部分将涉及一个可能在 IoTDB 操作中遇到的问题及其解决方法,即本地时区设置。

3. 设置时区

3.1 背景 & 问题


我们将之前例子中相同的一份 csv 的数据使用 import-csv 工具导入 IoTDB(使用默认参数),假如查询时间在 2022 年 1 月 12 日 11 点 48 分 43 秒之后的数据,只显示 10 条,输入的指令和输出结果如下:


IoTDB> select WROT_HubTmp from root.BHSFC.Q1.W002 where time>=2022-01-12T11:48:43.000 limit 10+-----------------------------+------------------------------+| Time|root.BHSFC.Q1.W002.WROT_HubTmp|+-----------------------------+------------------------------+|2022-01-12T11:48:43.000-08:00| 19.2||2022-01-12T11:48:49.000-08:00| 19.3||2022-01-12T11:49:02.000-08:00| 19.2||2022-01-12T11:49:08.000-08:00| 19.1||2022-01-12T11:49:59.000-08:00| 19.0||2022-01-12T11:51:31.000-08:00| 18.89999||2022-01-12T11:51:38.000-08:00| 19.0||2022-01-12T11:51:54.000-08:00| 18.89999||2022-01-12T11:52:42.000-08:00| 19.0||2022-01-12T11:55:01.000-08:00| 18.89999|+-----------------------------+------------------------------+Total line number = 10


可见当我们查询特定时间范围内的数据,查询结果是正常的。


但如果我们查询单行时间数据,且只限制时间格式而不指明时区查询,查询结果则可能出现问题。


如输入查询时间在 2022 年 1 月 12 日 10 点 48 分 51 秒的指令,输出结果如下:


IoTDB> select WROT_HubTmp from root.BHSFC.Q1.W002 where time=2022-01-12T10:48:51.000+----+------------------------------+|Time|root.BHSFC.Q1.W002.WROT_HubTmp|+----+------------------------------++----+------------------------------+Empty set.


可见查询为空,但我们的原始数据是有这个时间对应的数据的,这一行不应为空。

3.2 解决思路


IoTDB 中的数据点是以时间戳保存的,查询的时候则会以当前系统默认时区来转换成对应时间。


范围查询正常,但是单点查询不行,这个时候一般是时区出现了问题,需要进行时区设置。

3.2.1 解决方法一


我们可以在查询的时间后面增加时区。


使用 'show version' 命令查看 IoTDB 时区,可以看到时区为 'America/Los_Angeles',即西八区(UTC/GMT -8.00)。查看时区的指令和输出结果如下:


IoTDB> show time_zoneCurrent time zone: America/Los_Angeles


这种情况下,我们只需在单点查询的时间最后增加 '-08:00' ,就能查询到数值了。输入的指令和输出结果如下:


IoTDB> select WROT_HubTmp from root.BHSFC.Q1.W002 where time=2022-01-12T10:48:51.000-08:00+-----------------------------+------------------------------+| Time|root.BHSFC.Q1.W002.WROT_HubTmp|+-----------------------------+------------------------------+|2022-01-12T10:48:51.000-08:00| 18.3|+-----------------------------+------------------------------+Total line number = 1


可以看到问题得以解决,但此方法比较繁琐。

3.2.2 解决方法二


连接 IoTDB 服务器时,会使用服务器的默认时区作为 IoTDB 的默认时区,我们可以将系统的默认时区与 IoTDB 的时区保持相同。


我们可以使用 Linux 操作系统的 'timedatectl' 命令看到 'Time zone: America/Los_Angeles (PDT, -0700)'。命令和执行结果如下:


[root@localhost sbin]# timedatectlLocal time: Mon 2022-07-04 01:37:48 PDTUniversal time: Mon 2022-07-04 08:37:48 UTCRTC time: Mon 2022-07-04 08:37:48Time zone: America/Los_Angeles (PDT, -0700)


此时发现系统的默认时区变成了 America/Los_Angeles (PDT, -0700),我们将 IoTDB 的时区改为同样的 -0700 即可,命令和执行结果如下:


IoTDB> set time_zone=-07:00Time zone has set to -07:00


此时我们再执行单点查询就可以正确的查出数据,命令和执行结果如下:


IoTDB> select WROT_HubTmp from root.BHSFC.Q1.W002 where time=2022-01-12T11:48:51.000+-----------------------------+------------------------------+| Time|root.BHSFC.Q1.W002.WROT_HubTmp|+-----------------------------+------------------------------+|2022-01-12T11:48:51.000-07:00| 18.3|+-----------------------------+------------------------------+Total line number = 1

3.3 总结


PST 是 Pacific Standard Time 太平洋标准时间(-08:00)。PDT 是 Pacific Daylight Time 太平洋夏季时间(-07:00),始于每年 4 月的第 1 个周日,止于每年 10 月的最后一个周日。处于西八区(PST)的大部分城市都会使用夏令时。


当操作系统的时区设置为西八区(PST)时,会自动采用夏令时(-07:00),但是 IoTDB 依然是(-08:00)时,就导致了上述可能的查询错误。


国内用户出现上述问题一般为操作系统的时区设置错误,只需要时区设置为正确的东八区后重启 IoTDB 即可。

4. 结语


到这里,IoTDB 的小白教程文档已经全部呈现完毕。通过文档,大家对于 Apache IoTDB 的应用背景、产品性质、性能优势、架构分布、功能实现应该都有了基本的认知。感谢大家的关注,希望这个系列文档能够更好地帮助大家了解 IoTDB,使用 IoTDB!

发布于: 刚刚阅读数: 3
用户头像

Apache IoTDB

关注

还未添加个人签名 2021-12-30 加入

海量时序数据管理的解决方案,一款高吞吐、高压缩、高可用、物联网原生的开源时序数据库。

评论

发布
暂无评论
IoTDB 可实现的基本操作 —— 数据写入、删除、导出、元数据管理、时区设置 | 小白教程文档(四)_时序数据库_Apache IoTDB_InfoQ写作社区