IoTDB入门教程
IoTDB是一个用 Java编写的面向列的 开源时序数据库(TSDB)管理系统。
# 什么是时序数据?
时序数据是指时间序列数据,是按时间顺序记录的数据列。工业物联网中,机器设备、传感器实时产生了海量时序数据,是工业数据的主体(占80%以上)。 工业物联网时序数据管理是工业互联网应用落地的基础。
# 架构
IoTDB 套件由若干个组件构成,共同形成“数据收集-数据写入-数据存储-数据查询-数据可视化-数据分析”等一系列功能。
如下图展示了使用 IoTDB 套件全部组件后形成的整体应用架构。下文称所有组件形成 IoTDB 套件,而 IoTDB 特指其中的时间序列数据库组件。
# 特点
灵活的部署方式
- 云端一键部署
- 终端解压即用
- 终端-云端无缝连接(数据云端同步工具)
低硬件成本的存储解决方案
- 高压缩比的磁盘存储(10 亿数据点硬盘成本低于 1.4 元)
目录结构的时间序列组织管理方式
- 支持复杂结构的智能网联设备的时间序列组织
- 支持大量同类物联网设备的时间序列组织
- 可用模糊方式对海量复杂的时间序列目录结构进行检索
高通量的时间序列数据读写
- 支持百万级低功耗强连接设备数据接入(海量)
- 支持智能网联设备数据高速读写(高速)
- 以及同时具备上述特点的混合负载
面向时间序列的丰富查询语义
- 跨设备、跨传感器的时间序列时间对齐
- 面向时序数据特征的计算
- 提供面向时间维度的丰富聚合函数支持
极低的学习门槛
- 支持类 SQL 的数据操作
- 提供 JDBC(Java DataBase Connectivity) 的编程接口
- 完善的导入导出工具
完美对接开源生态环境
- 支持开源数据分析生态系统:Hadoop、Spark
- 支持开源可视化工具对接:Grafana
# 数据模型
以实际工业应用场景为例,如下图,电力集团 BHSFC ,拥有 Q1 风电厂,风电厂有一座名为 W002 的风机,风机上测量的数据即轮毂温度命名为 WROT_HubTmp 。
IoTDB 采用树形结构定义数据模式,根节点默认为 root ,节点之间用“.”分割。上述例子中涉及的数据的时间序列在IoTDB中会被命名为“root.BHSFC.Q1.W002.WROT_HubTmp”。
在 IoTDB 中处理此场景内的数据,表头将修改为如下样式,即 “Time” 和“root.BHSFG.Q1.W002.WROT_HubTmp”字段。
# 物理量、实体、数据库、路径
# 物理量(Measurement)
物理量,也称工况或字段(field),是在实际场景中检测装置所记录的测量信息,且可以按一定规律变换成为电信号或其他所需形式的信息输出并发送给 IoTDB。在 IoTDB 当中,存储的所有数据及路径,都是以物理量为单位进行组织。
# 实体(Entity)
一个物理实体,也称设备(device),是在实际场景中拥有物理量的设备或装置。在 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
下的两个实体 wt01
, wt02
可能属于同一个业主,或者同一个制造商,这时候就可以将前缀路径root.ln
指定为一个数据库。未来root.ln
下增加了新的实体,也将属于该数据库。
一个 database 中的所有数据会存储在同一批文件夹下,不同 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
# 时间序列
# 时间戳 (Timestamp)
时间戳是一个数据到来的时间点,其中包括绝对时间戳和相对时间戳,详细描述参见 数据类型文档 (opens new window)。
# 数据点(Data Point)
一个“时间戳-值”对。
# 时间序列(Timeseries)
一个物理实体的某个物理量在时间轴上的记录,是数据点的序列。
一个实体的一个物理量对应一个时间序列,即实体+物理量=时间序列。
时间序列也被称测点(meter)、时间线(timeline)。实时数据库中常被称作标签(tag)、参数(parameter)。
例如,ln 电力集团、wf01 风电场的实体 wt01 有名为 status 的物理量,则它的时间序列可以表示为:root.ln.wf01.wt01.status
。
# 对齐时间序列(Aligned Timeseries)
在实际应用中,存在某些实体的多个物理量同时采样,形成一组时间列相同的时间序列,这样的一组时间序列在Apache IoTDB中可以建模为对齐时间序列。
在插入数据时,一组对齐序列的时间戳列在内存和磁盘中仅需存储一次,而不是每个时间序列存储一次。
对齐的一组时间序列最好同时创建。
不可以在对齐序列所属的实体下创建非对齐的序列,不可以在非对齐序列所属的实体下创建对齐序列。
查询数据时,可以对于每一条时间序列单独查询。
插入数据时,对齐的时间序列中某列的某些行允许有空值。
# 数据类型
# 基本数据类型
IoTDB 支持以下六种数据类型:
- BOOLEAN(布尔值)
- INT32(整型)
- INT64(长整型)
- FLOAT(单精度浮点数)
- DOUBLE(双精度浮点数)
- TEXT(字符串)
# 浮点数精度配置
对于 FLOAT 与 DOUBLE 类型的序列,如果编码方式采用 RLE (opens new window) 或 TS_2DIFF (opens new window) ,可以在创建序列时通过 MAX_POINT_NUMBER
属性指定浮点数的小数点后位数。
例如,
CREATE TIMESERIES root.vehicle.d0.s0 WITH DATATYPE=FLOAT, ENCODING=RLE, 'MAX_POINT_NUMBER'='2';
若不指定,系统会按照配置文件 iotdb-common.properties
中的 float_precision (opens new window) 项配置(默认为 2 位)。
# 数据类型兼容性
当写入数据的类型与序列注册的数据类型不一致时,
- 如果序列数据类型不兼容写入数据类型,系统会给出错误提示。
- 如果序列数据类型兼容写入数据类型,系统会进行数据类型的自动转换,将写入的数据类型更正为注册序列的类型。
各数据类型的兼容情况如下表所示:
序列数据类型 | 支持的写入数据类型 |
---|---|
BOOLEAN | BOOLEAN |
INT32 | INT32 |
INT64 | INT32 INT64 |
FLOAT | INT32 FLOAT |
DOUBLE | INT32 INT64 FLOAT DOUBLE |
TEXT | TEXT |
# 时间戳类型
时间戳是一个数据到来的时间点,其中包括绝对时间戳和相对时间戳。
# 绝对时间戳
IOTDB 中绝对时间戳分为二种,一种为 LONG 类型,一种为 DATETIME 类型(包含 DATETIME-INPUT, DATETIME-DISPLAY 两个小类)。
在用户在输入时间戳时,可以使用 LONG 类型的时间戳或 DATETIME-INPUT 类型的时间戳,其中 DATETIME-INPUT 类型的时间戳支持格式如表所示:
DATETIME-INPUT 类型支持格式
format |
---|
yyyy-MM-dd HH:mm:ss |
yyyy/MM/dd HH:mm:ss |
yyyy.MM.dd HH:mm:ss |
yyyy-MM-dd HH:mm:ssZZ |
yyyy/MM/dd HH:mm:ssZZ |
yyyy.MM.dd HH:mm:ssZZ |
yyyy/MM/dd HH:mm:ss.SSS |
yyyy-MM-dd HH:mm:ss.SSS |
yyyy.MM.dd HH:mm:ss.SSS |
yyyy-MM-dd HH:mm:ss.SSSZZ |
yyyy/MM/dd HH:mm:ss.SSSZZ |
yyyy.MM.dd HH:mm:ss.SSSZZ |
ISO8601 standard time format |
IoTDB 在显示时间戳时可以支持 LONG 类型以及 DATETIME-DISPLAY 类型,其中 DATETIME-DISPLAY 类型可以支持用户自定义时间格式。自定义时间格式的语法如表所示:
DATETIME-DISPLAY 自定义时间格式的语法
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G | era | era | era |
C | century of era (>=0) | number | 20 |
Y | year of era (>=0) | year | 1996 |
x | weekyear | year | 1996 |
w | week of weekyear | number | 27 |
e | day of week | number | 2 |
E | day of week | text | Tuesday; Tue |
y | year | year | 1996 |
D | day of year | number | 189 |
M | month of year | month | July; Jul; 07 |
d | day of month | number | 10 |
a | halfday of day | text | PM |
K | hour of halfday (0~11) | number | 0 |
h | clockhour of halfday (1~12) | number | 12 |
H | hour of day (0~23) | number | 0 |
k | clockhour of day (1~24) | number | 24 |
m | minute of hour | number | 30 |
s | second of minute | number | 55 |
S | fraction of second | millis | 978 |
z | time zone | text | Pacific Standard Time; PST |
Z | time zone offset/id | zone | -0800; -08:00; America/Los_Angeles |
' | escape for text | delimiter | |
'' | single quote | literal | ' |
# 相对时间戳
相对时间是指与服务器时间now()
和DATETIME
类型时间相差一定时间间隔的时间。
形式化定义为:
Duration = (Digit+ ('Y'|'MO'|'W'|'D'|'H'|'M'|'S'|'MS'|'US'|'NS'))+
RelativeTime = (now() | DATETIME) ((+|-) Duration)+
2
The syntax of the duration unit
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
y | year | 1y=365 days | 1y |
mo | month | 1mo=30 days | 1mo |
w | week | 1w=7 days | 1w |
d | day | 1d=1 day | 1d |
h | hour | 1h=3600 seconds | 1h |
m | minute | 1m=60 seconds | 1m |
s | second | 1s=1 second | 1s |
ms | millisecond | 1ms=1000_000 nanoseconds | 1ms |
us | microsecond | 1us=1000 nanoseconds | 1us |
ns | nanosecond | 1ns=1 nanosecond | 1ns |
例子:
now() - 1d2h //比服务器时间早 1 天 2 小时的时间
now() - 1w //比服务器时间早 1 周的时间
2
注意:'+'和'-'的左右两边必须有空格