Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

一、数据模型

1、 一元时间序列

时间序列是IoTDB中的核心概念。时间序列可以被看作产生时序数据的物理量的所在完整路径,在IoTDB中所有的时间序列必须以root开始、以物理量作为结尾。一个时间序列也可称为一个全路径。

一元时间序列指的是在同一个时间戳,仅有一个物理量采样,形成的一条时间序列。

2、多元时间序列

在同一个时间戳有多个物理量同时采样,会形成具有相同时间戳的多条一元时间序列,在 IoTDB 中,这些时间序列成为多元时间序列(学术界的定义为:即包含多个一元时间序列作为分量, 各个一元时间序列的采样时间点相同)

创建多元时间序列时,可以使用关键字 aligned 显式指明。

多元时间序列可以被同时创建,同时插入值,删除时也必须同时删除。不过在查询的时候,可以对于每一个物理量单独查询。

通过使用多元时间序列,在插入数据时,多元序列的时间戳列在内存和磁盘中仅需存储一次,而不是物理量的个数次。

多元时间序列不支持序列嵌套、不支持多时间戳(目前IoTDB均不支持)

3、“设备”的定义

设备指的是在实际场景中拥有物理量的装置,即序列(一元/多元)的上一层,即IoTDB概念中的实体(Entity)。

应用场景

场景1:一个物理设备具有多个一元序列

...

1、物理量(Measurement,也称工况、字段 field)

物理量,是在实际场景中检测装置所记录的测量信息,且可以按一定规律变换成为电信号或其他所需形式的信息输出并发送给 IoTDB。在 IoTDB 当中,存储的所有数据及路径,都是以物理量为单位进行组织。

2、实体(Entity,也称设备,device)

一个物理实体,是在实际场景中拥有物理量的设备或装置。在 IoTDB 当中,所有的物理量都有其对应的归属实体。

3、存储组(Storage group)

一组物理实体,用户可以将任意前缀路径设置成存储组。

4、数据点(Data point)

一个“时间-值”对

5、时间序列(一个实体的某个物理量对应一个时间序列,Timeseries,也称测点 meter、时间线 timeline,实时数据库中常被称作标签 tag、参数 parameter)

一个物理实体的某个物理量在时间轴上的记录,是数据点的序列。

6、对齐的时间序列(Aligned timeseries)

在实际应用中,存在某些实体的多个物理量同时采样(如 GPS 的经度和维度),形成在时间列上对齐的多条时间序列。

对齐时间序列的时间戳列在内存和磁盘中仅需存储一次,可以减少存储资源的占用。

对齐的多个时间序列需要同时创建,使用关键字 aligned 显式声明

不可以在对齐序列所属的设备下创建非对齐的序列,不可以在非对齐序列所属的设备下创建对齐序列。

查询数据时,可以对于每一条时间序列单独查询。

插入数据时,对齐的时间序列中某列的某些行允许有空值。

7、物理量模板(Schema template)

实际应用中有许多实体所采集的物理量相同,即具有相同的工况名称和类型,可以声明一个物理量模板来定义可采集的物理量集合。在实践中,物理量模板的使用可帮助减少元数据的资源占用。

应用场景与 SQL 设计

场景1:一个物理实体具有多个非对齐的时间序列

Code Block
languagesql
themeConfluence
// 创建时间序列
// 1. 完整语法(v0.12及之前)
create timeseries root.

...

sg1.d1.

...

s1 with datatype=FLOAT, encoding=RLE, compression=SNAPPY, tags(tag1=v1, tag2=v2), attributes(attr1=v1, attr2=v2)
create timeseries root.sg1.d1.s2 with datatype=FLOAT, encoding=RLE,

...

 compression=SNAPPY,

...

 

...

tags(tag1=v1, tag2=v2),

...

 

...

attributes(attr1=v1, attr2=v2)

...

// 

...

2. 简化语法(v0.13开始支持,与之前语法兼容)
create timeseries root.

...

sg1.

...

d1.s1 FLOAT 

...

encoding=RLE

...

 

...

compression=SNAPPY

...

 

...

tags(tag1=v1, tag2=v2)

...

 

...

attributes(attr1=v1, attr2=v2)

...


create timeseries root.

...

sg1.

...

d1.s2 FLOAT 

...

encoding=RLE

...

 

...

compression=SNAPPY

...

 

...

tags(tag1=v1, tag2=v2)

...

 

...

attributes(attr1=v1, attr2=v2)

...



// 插入语句
insert into root.

...

sg1.

...

d1(time, s1) values(1,1)

...


insert into root.

...

sg1.

...

d1(time, s1, s2) values(1,1,2)

...

场景2:一个物理实体具有一组对齐的时间序列

Code Block
languagesql
themeConfluence
//

...

 在实体 root.sg1.

...

d2 下创建一组对齐的时间序列
create aligned timeseries root.sg1.

...

d2(s1 FLOAT encoding=RLE

...

,

...

 s2 INT32

...

 encoding=Grollia

...

 compression=SNAPPY)

/

...

/ 注:可以指定每条时间序列的编码(encoding)和压缩方式(compression),但是暂不支持指定 props, attributes, tags 等。

// 插入语句,必须使用 aligned 关键词
insert into root.sg.

...

d2(time,

...

 s1, s2)

...

 aligned values(1,

...

 1, 2)

...

注意:场景2所创建的多元时间序列所属实体可以扩充一元或多元物理量

例如,可以向d1下继续添加一元时间序列,为d1 扩充 d1.c 序列:

...


insert into root.

...

场景3:(场景2的特例)一个物理设备仅有一个多元序列,可省略多元序列名字

...

sg.d2(time, s1) aligned values(2, 1)  //允许单独写某条时间序列,其他时间序列在该时间点上为空值

// 场景2所创建的对齐时间序列所属物理实体可以扩充时间序列,但需要在该物理实体下嵌套新实体。
// 例如,可以向d2下继续添加时间序列: 
create timeseries root.sg1.

...

d2.

...

t1.

...

s1 FLOAT

...


create timeseries root.sg1.d2.v1.(s1 FLOAT, s2 FLOAT)

场景3:一个物理实体具有多组对齐的时间序列

Code Block
languagesql
themeConfluence

...

注意:按照场景3的方式创建多元时间序列后,不能进行进一步扩充。

...

// 创建语句
create 

...

aligned

...

 timeseries root.

...

sg1.d3.

...

v1(s1 FLOAT, s2 INT32)
create 

...

aligned

...

 timeseries root.

...

sg1.d3.

...

v2(

...

s1 FLOAT, 

...

s2 INT32)
 

...

// 

...

插入语句,不能同时向多组对齐的时间序列中插入值
insert into root.

...

sg1.d3.v1(time, 

...

s1, s2)

...

 

...

aligned values(1, 

...

1, 2)
insert into root.sg1.d3.v1(time, s1) aligned values(2, 3

...

)
insert into root.

...

sg1.d3.v2(time, 

...

s1, s2)

...

 aligned values(1, 

...

1, 2

...

)

...

注意:场景4所创建的多元时间序列是可以扩充的。例如,可以向d3下继续添加其他的一元或多元时间序列:

create timeseries root.sg.d3.s3 FLOAT

场景5:一个物理设备具有混合的多元序列和一元序列

...

insert into root.sg1.d3.v2(time, s2) aligned values(3, 4)

场景4:一个物理实体具有混合的非对齐和对齐的时间序列

Code Block
languagesql
themeConfluence
// 创建语句
create timeseries root.sg1.d4.t1.s1 FLOAT
create aligned timeseries root.sg1.d4.v1(s1 FLOAT, s2 INT32)
create aligned timeseries root.sg1.d4.v2(s1 FLOAT, s2 INT32)

// 插入语句,不能同时向非对齐和对齐的时间序列中插入值
insert into root.sg1.d4.t1(time, s1) values(1, 1)
insert into root.sg1.d4.v1(time, s1, s2) aligned values(1, 1, 2)
insert into root.

...

sg1.d4.

...

v1(time,

...

 s1) aligned values(2, 

...

3)
insert into root.sg1.d4.v2(time, s1, s2) aligned values(1, 

...

1, 2)
insert into root.sg1.d4.v2(time, s2) aligned values(3, 4)

三、Session API

注意:以下仅展示本次新增的 session API,其他 API 与旧有 API 相同的不在此展示,如:查询语句(executeRawDataQuery)。

1、多元时间序列相关 API

...

1、创建一组对齐的时间序列

Code Block
languagejava
themeConfluence
void createAlignedTimeseries(

...

	String prefixPath, // "root.sg.d1.陀螺仪" 

...

	List<String> measurements,

...

	List<TSDataType> dataTypes,

...

	List<TSEncoding> encodings, 

...

	CompressionType compressor, 

...

	List<String> measurementAliasList
);

2、插入Record

一个 Record 是一个设备一个时间戳下多个测点的数据,例如:

insert into root.sg1.sgd1.d3v1(time, 陀螺仪(s1, s2)) aligned values(1,(1,2))

API 如下:

Code Block
languagejava
themeConfluence
// 服务器需要做类型推断,可能会有额外耗时
void insertAlignedRecord(String prefixPath, long time, List<String> measurements, List<String> values)

...

// 提供数据类型后,服务器不需要做类型推断,可以提高性能
void insertAlignedRecord(String prefixPath, long time, List<String> measurements, List<TSDataType> types, List<Object> values

...

应用到上面的例子即:

)

// 应用到上面的例子即:
void insertAlignedRecord(
    "root.

...

sg1.

...

d1.

...

v1",
    1,
    Arrays.asList("s1", "s2"),
    Arrays.asList("1", "2")
)

...

注意:当前仅支持 record 插入一个多元时间序列。后期将适配如下 SQL(即在同一个 record 中涉及多个多元时间序列、或涉及混合的一元和多元时间序列)

...



// 只插入到部分序列,其他序列值自动置为 null
void insertAlignedRecord(
    "root.sg1.d1.v1",
    1,
    Arrays.asList("s1"),
    Arrays.asList("1")
)

// 也可以通过null显式声明
void insertAlignedRecord(
    "root.sg1.d1.v1",
    1,
    Arrays.asList("s1","s2"),
    Arrays.asList("1",null)
)

3、插入Tablet

Tablet 是一个设备若干行非空数据块,每一行的列都相同

Code Block
languagejava
themeConfluence
// 插入一个 Tablet
void insertTablet(Tablet tablet)

...

 

// 插入多个 Tablet
void insertTablets(Map<String, Tablet> tablet)

...

多元时间序列通过 VectorMeasurementSchema 构建 Tablet

...



// 对齐的时间序列通过 measurementSchema 构建 Tablet
List<IMeasurementSchema> schemaList = new ArrayList<>();
schemaList.add(new

...

 measurementSchema(new String[] {"s1", "s2"}, new TSDataType[] {TSDataType.INT64, TSDataType.INT32}));
Tablet tablet = new Tablet("root.sg1.d1.

...

v1", schemaList);

...