...
数据类型
0: BOOLEAN
1: INT32 (
int
)2: INT64 (
long
)3: FLOAT
4: DOUBLE
5: TEXT (
String
)
编码类型
为了提高数据的存储效率,需要在数据写入的过程中对数据进行编码,从而减少磁盘空间的使用量。在写数据以及读数据的过程中都能够减少I/O操作的数据量从而提高性能。IoTDB支持多种针对不同类型的数据的编码方法:0: PLAIN
PLAIN编码,默认的编码方式,即不编码,支持多种数据类型,压缩和解压缩的时间效率较高,但空间存储效率较低。
1: DICTIONARY
- 字典编码是一种无损编码。它适合编码基数小的数据(即数据去重后唯一值数量小)。不推荐用于基数大的数据。
2: RLE
游程编码,比较适合存储某些整数值连续出现的序列,不适合编码大部分情况下前后值不一样的序列数据。
游程编码也可用于对浮点数进行编码,但在创建时间序列的时候需指定保留小数位数(MAX_POINT_NUMBER,具体指定方式参见本文SQL 参考文档)。比较适合存储某些浮点数值连续出现的序列数据,不适合存储对小数点后精度要求较高以及前后波动较大的序列数据。
游程编码(RLE)和二阶差分编码(TS_2DIFF)对 float 和 double 的编码是有精度限制的,默认保留2位小数。推荐使用 GORILLA。
3: DIFF
4: TS_2DIFF
- 二阶差分编码,比较适合编码单调递增或者递减的序列数据,不适合编码波动较大的数据。
5: BITMAP
6: GORILLA_V1
GORILLA编码是一种无损编码,它比较适合编码前后值比较接近的数值序列,不适合编码前后波动较大的数据。
当前系统中存在两个版本的GORILLA编码实现,推荐使用
GORILLA
,不推荐使用GORILLA_V1
(已过时)。使用限制:使用Gorilla编码INT32数据时,需要保证序列中不存在值为
Integer.MIN_VALUE
的数据点;使用Gorilla编码INT64数据时,需要保证序列中不存在值为Long.MIN_VALUE
的数据点。
7: REGULAR
8: GORILLA
9: ZigZag
- ZigZag编码将有符号整型映射到无符号整型,适合比较小的整数。
数据类型与支持编码的对应关系
数据类型 支持的编码 BOOLEAN PLAIN, RLE INT32 PLAIN, RLE, TS_2DIFF, GORILLA, ZigZag INT64 PLAIN, RLE, TS_2DIFF, GORILLA, ZigZag FLOAT PLAIN, RLE, TS_2DIFF, GORILLA DOUBLE PLAIN, RLE, TS_2DIFF, GORILLA TEXT PLAIN, DICTIONARY
压缩类型
...
0: UNCOMPRESSED
1
...
2: GZIP
...
3: LZO
...
4: SDT
...
5: PAA
...
6: PLA
...
7: LZ4
1.2 TsFile 概述
TsFile 整体分为两大部分:数据区和索引区。
...
索引树节点的度(即每个节点的最大子节点个数)可以由用户进行配置,配置项为max_degree_of_index_node
,其默认值为256。在以下例子中,我们假定 max_degree_of_index_node = 10
。
需要注意的是,在索引树的每类节点(ENTITY、MEASUREMENT)中,键按照字典序排列。在下面的例子中,若i<j,假设字典序di<dj。(否则,实际上[d1,d2,...d10]的字典序排列应该为[d1,d10,d2,...d9])
其中,例1~4为一元时间序列的例子,例5~6为多元时间序列的例子,例7为综合例子。
...
在150个实体,每个实体中有150个物理量的情况下,物理量和实体个数均超过了 max_degree_of_index_node
,形成索引树的物理量层级和实体索引层级。在这两个层级里,每个 IndexNode 均最多由10个 IndexEntry 组成。如前所述,从根节点到实体索引层级的叶子节点,类型分别为INTERNAL_ENTITY
和 LEAF_ENTITY
,而每个实体索引层级的叶子节点都是物理量索引层级的根节点,从这里到物理量索引层级的叶子节点,类型分别为INTERNAL_MEASUREMENT
和 LEAF_MEASUREMENT
。
例5:1个实体,20个物理量,2个多元时间序列组,每个多元时间序列组分别有9个物理量例5:1个实体,18个物理量,2个多元时间序列组,每个多元时间序列组分别有9个物理量
例6:1个实体,30个物理量,2个多元时间序列组,每个多元时间序列组分别有15个物理量
...
注意: 如果没有设置输出文件的存储路径, 将使用 "TsFile_sketch_view.txt" 做为默认值。
在mac系统中的示例:
/iotdb/server/target/iotdb-server-{version}/tools/tsfileToolSet$ ./print-tsfile-sketch.sh test.tsfile
|````````````````````````
Starting Printing the TsFile Sketch
|````````````````````````
TsFile path:test.tsfile
Sketch save path:TsFile_sketch_view.txt
-------------------------------- TsFile Sketch --------------------------------
file path: test.tsfile
file length:
...
15462
14:40:55.619 [main] INFO org.apache.iotdb.tsfile.read.TsFileSequenceReader - Start reading file test.tsfile metadata from 15356, length 96
POSITION| CONTENT
-------- -------
...
0|
...
[magic head] TsFile
...
6|
...
[version number]
...
3
||||||||||||||||||||| [Chunk Group] of root.
...
sg_
...
1.
...
d1, num of Chunks:
...
4
7| [Chunk Group Header]
...
| [marker] 0
...
|
...
...
...
...
...
...
[
...
deviceID] root.sg_1.d1
21| [Chunk] of s6, numOfPoints:1000, time range:[0,999], tsDataType:INT64,
startTime: 0 endTime: 999 count: 1000 [minValue:6,maxValue:9996,firstValue:6,lastValue:9996,sumValue:5001000.0]
| [chunk
...
header] marker=5, measurementId=s6, dataSize=1826, serializedSize=9
|
...
[
...
chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
| [page] CompressedSize:1822, UncompressedSize:1951
...
...
...
...
1856|
...
...
[
...
Chunk] of s4, numOfPoints:1000, time range:[0,999], tsDataType:INT64,
startTime: 0 endTime: 999 count: 1000 [minValue:4,maxValue:9994,firstValue:4,lastValue:9994,sumValue:4999000.0]
| [chunk
...
header] marker=5, measurementId=s4, dataSize=1826, serializedSize=9
| [chunk] java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
|
...
...
[page] CompressedSize:1822, UncompressedSize:1951
3691|
...
[Chunk] of
...
s2, numOfPoints:
...
1000, time range:[
...
0,
...
999], tsDataType:INT64,
...
...
startTime:
...
0 endTime:
...
999 count:
...
1000 [minValue:
...
3,maxValue:
...
9993,firstValue:
...
3,lastValue:
...
9993,sumValue:
...
4998000.0]
| [chunk
...
header] marker=5, measurementId=s2, dataSize=1826, serializedSize=9
| [chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
| [page]
...
CompressedSize:1822, UncompressedSize:1951
5526| [Chunk] of s5, numOfPoints:1000, time range:[0,999], tsDataType:INT64,
startTime: 0 endTime: 999 count: 1000 [minValue:5,maxValue:9995,firstValue:5,lastValue:9995,sumValue:5000000.0]
| [chunk
...
header] marker=5, measurementId=s5, dataSize=1826, serializedSize=9
| [chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
|
...
[page] CompressedSize:1822, UncompressedSize:1951
||||||||||||||||||||| [Chunk Group] of root.
...
sg_
...
1.
...
d1 ends
...
||||||||||||||||||||| [Chunk Group] of root.sg_1.d2, num of Chunks:4
...
...
7361| [Chunk Group Header]
| [marker]
...
0
| [deviceID] root.sg_1.d2
...
...
7375| [Chunk] of
...
s2, numOfPoints:
...
1000, time range:[
...
0,
...
999], tsDataType:
...
INT64,
...
startTime:
...
0 endTime:
...
999 count:
...
1000 [minValue:
...
3,maxValue:
...
9993,firstValue:
...
3,lastValue:
...
9993,sumValue:
...
4998000.0]
| [chunk
...
header] marker=5, measurementId=s2, dataSize=1826, serializedSize=9
| [chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
| [page]
...
CompressedSize:1822, UncompressedSize:1951
...
9210|
...
[Chunk] of
...
s4, numOfPoints:
...
1000, time range:[
...
0,
...
999], tsDataType:
...
INT64,
...
startTime:
...
0 endTime:
...
999 count:
...
1000 [minValue:
...
4,maxValue:
...
9994,firstValue:
...
4,lastValue:
...
9994,sumValue:
...
4999000.0]
| [chunk
...
header] marker=5, measurementId=s4, dataSize=1826, serializedSize=9
|
...
[chunk] java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
| [page]
...
CompressedSize:1822, UncompressedSize:1951
...
11045|
...
[Chunk] of
...
s6, numOfPoints:
...
1000, time range:[
...
0,
...
999], tsDataType:
...
INT64,
...
startTime:
...
0 endTime:
...
999 count:
...
1000 [minValue:
...
6,maxValue:
...
9996,firstValue:
...
6,lastValue:
...
9996,sumValue:
...
5001000.0]
| [chunk
...
header] marker=5, measurementId=s6, dataSize=1826, serializedSize=9
| [chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
| [page]
...
CompressedSize:1822, UncompressedSize:1951
12880| [Chunk] of s5, numOfPoints:1000, time range:[0,999], tsDataType:INT64,
startTime: 0 endTime: 999 count: 1000 [minValue:5,maxValue:9995,firstValue:5,lastValue:9995,sumValue:5000000.0]
| [chunk
...
header] marker=5, measurementId=s5, dataSize=1826, serializedSize=9
| [chunk]
...
java.nio.HeapByteBuffer[pos=0 lim=1826 cap=1826]
|
...
[page] CompressedSize:1822, UncompressedSize:1951
||||||||||||||||||||| [Chunk Group] of root.
...
sg_
...
1.
...
d2 ends
14715| [marker] 2
...
14716| [
...
TimeseriesIndex]
...
of root.sg_1.d1.s2, tsDataType:INT64
...
|
...
...
[
...
ChunkIndex]
...
s2, offset=3691
| [startTime: 0
...
endTime: 999 count:
...
1000 [minValue:3,maxValue:9993,firstValue:3,lastValue:9993,sumValue:4998000.0]]
14788| [TimeseriesIndex] of root.
...
sg_
...
1.d1.
...
s4,
...
tsDataType:INT64
|
...
...
...
[ChunkIndex] s4, offset=1856
|
...
[startTime:
...
0 endTime:
...
999 count:
...
1000 [minValue:4,maxValue:9994,firstValue:
...
4,lastValue
...
:9994,sumValue:4999000.0]]
...
14860| [
...
TimeseriesIndex] of root.sg_1.d1.s5, tsDataType:INT64
|
...
[ChunkIndex] s5, offset=5526
|
...
[startTime: 0 endTime:
...
999
...
count: 1000 [minValue:5,maxValue:9995,firstValue:5,lastValue:9995,sumValue:5000000.0]]
14932|
...
[
...
TimeseriesIndex] of
...
root.sg_1.d1.s6, tsDataType:
...
INT64
| [ChunkIndex] s6, offset=21
...
| [startTime: 0 endTime:
...
999 count:
...
1000 [minValue:6,maxValue:9996,firstValue:
...
6,lastValue:
...
9996,sumValue:5001000.0]]
...
15004| [
...
TimeseriesIndex] of root.sg_1.d2.s2, tsDataType:INT64
| [ChunkIndex]
...
s2, offset=7375
| [startTime: 0 endTime: 999 count:
...
1000 [minValue:3,maxValue:9993,firstValue:3,lastValue:9993,sumValue:4998000.0]]
15076| [TimeseriesIndex] of root.sg_1.d2.s4, tsDataType:INT64
|
...
...
[
...
ChunkIndex]
...
s4, offset=9210
| [startTime: 0
...
endTime: 999 count:
...
1000 [minValue:4,maxValue:9994,firstValue:4,lastValue:9994,sumValue:4999000.0]]
15148| [TimeseriesIndex] of root.sg_1.d2.s5, tsDataType:INT64
| [ChunkIndex] s5, offset=12880
|
...
...
...
...
[startTime: 0 endTime: 999 count: 1000 [minValue:5,maxValue:9995,firstValue:5,lastValue:9995,sumValue:5000000.0]]
15220| [TimeseriesIndex] of root.sg_1.d2.s6, tsDataType:INT64
|
...
[ChunkIndex] s6, offset=11045
| [startTime: 0 endTime:
...
999 count: 1000 [
...
minValue:6,maxValue:9996,firstValue:6,lastValue:9996,sumValue:5001000.0]]
...
|||||||||||||||||||||
...
...
...
15292| [IndexOfTimerseriesIndex Node] type=LEAF_MEASUREMENT
...
|
...
...
...
...
...
...
<s2, 14716>
| <s6, 14932>
...
| <endOffset, 15004>
15324| [IndexOfTimerseriesIndex
...
Node] type=LEAF_MEASUREMENT
| <s2, 15004>
...
...
| <s6, 15220>
...
|
...
...
<endOffset, 15292>
...
15356|
...
...
...
[TsFileMetadata]
| [meta
...
offset] 14715
| [num of devices] 2
...
...
| 2 key&TsMetadataIndex
|
...
...
[bloom filter bit vector byte array length] 32
|
...
...
...
...
[bloom filter bit vector byte array]
|
...
[
...
bloom filter number of bits] 256
| [bloom filter
...
number of hash
...
functions]
...
5
15452|
...
[TsFileMetadataSize] 96
15456| [magic tail] TsFile
15462| END of TsFile
---------------------------- IndexOfTimerseriesIndex Tree -----------------------------
[MetadataIndex:LEAF_DEVICE]
└───[root.sg_1.d1,15292]
[MetadataIndex:LEAF_MEASUREMENT]
...
└───[s2,14716]
└───[s6,14932]
└───[root.sg_1.d2,15324]
...
[MetadataIndex:LEAF_MEASUREMENT]
...
└───[s2,15004]
...
└───[s6,15220]]
----------------------------------
...
TsFile Sketch End ----------------------------------
3.4 TsFileSequenceRead
您可以使用示例中的类 example/tsfile/org/apache/iotdb/tsfile/TsFileSequenceRead
顺序打印 TsFile 中的内容.
...
clear all;close all;
% 1. load visdata generated by TsFileExtractVisdata
filePath = 'D:\visdata1.csv';
[timeMap,countMap] = loadVisData(filePath,'ms'); % mind the timestamp unit
% 2. plot figures given the loaded data and two plot parameters:
% `showSpecific` and `isFileOrder`
draw(timeMap,countMap,{},false)
title("draw(timeMap,countMap,\{\},false)")
draw(timeMap,countMap,{},true)
title("draw(timeMap,countMap,\{\},true)")
draw(timeMap,countMap,{'root.vehicle.d0.s0'},false)
title("draw(timeMap,countMap,{'root.vehicle.d0.s0'},false)")
draw(timeMap,countMap,{'root.vehicle.d0.s0','root.vehicle.d0.s1'},false)
title("draw(timeMap,countMap,{'root.vehicle.d0.s0','root.vehicle.d0.s1'},false)")
draw(timeMap,countMap,{'root.vehicle.d0.s0','root.vehicle.d0.s1'},true)
title("draw(timeMap,countMap,{'root.vehicle.d0.s0','root.vehicle.d0.s1'},true)")
绘图结果:
...
.vehicle.d0.s1'},true)
title("draw(timeMap,countMap,{'root.vehicle.d0.s0','root.vehicle.d0.s1'},true)")
绘图结果:
附录
大端存储
比如:
int
0x8
将会被存储为00 00 00 08
, 而不是08 00 00 00
可变长的字符串类型
存储的方式是以一个
int
类型的Size
+ 字符串组成。Size
的值可以为 0。Size
指的是字符串所占的字节数,它并不一定等于字符串的长度。举例来说,"sensor_1" 这个字符串将被存储为
00 00 00 08
+ "sensor_1" (ASCII编码)。另外需要注意的一点是文件签名 "TsFile000001" (
Magic String
+Version
), 因为他的Size(12)
和 ASCII 编码值是固定的,所以没有必要在这个字符串前的写入Size
值。
压缩类型
0: UNCOMPRESSED
1: SNAPPY
2: GZIP
3: LZO
4: SDT
5: PAA
6: PLA
7: LZ4
...