从启动说起
有一个timestamp_precision的配置项文件名在IoTDB的配置文件里,默认是ms。但是大多数用户在使用IoTDB储存数据时,对这个配置项timestamp_precision不关注,而通过System.currentTime Millis在Java客户端拿到一个long类型的时间戳,刚好就是毫秒级别的,很合适。
所以大多数用户对这个都无感,但是也有一些场景,数据采集频率大于1000了,这时候大家就开始想着改这个参数了,比如改成ns。
然后就会遇到一个启动问题:
ConfigurationException:
Parameter timestamp_precision can not be ns, please set to: ms。
大家可能就蒙了,为啥不让改?
正好 0.13.1 版本发布了,接下来的介绍和截图也就用这个版本了。
能不能不管时间精度?
传给数据库的 Time 都是数字格式的时间戳,就不用管这个参数。
我们先启动一个 CLI,加一个参数:
./sbin/start-cli.sh -disableISO8601
然后执行下列 SQL:
insert into root.sg.d(time,s1) values(1,520)
insert into root.sg.d(time,s1) values(2,520)
select s1 from root.sg.d where time<10
接下来,我们会看到下面这种结果,从写入的SQL,到查询出的结果的Time列展示,都跟时间精度没关系,时间戳都只是一个整数。
我们把这个 1、2 当做ms也可以,当做us、ns都可以。
这就是最原始的样子,没有时间精度,时间戳就是一个long类型的数据,数据库接收到这个long,就存储这个long,并且查询的时候把这个long返回给客户端。
所以,如果用long类型的时间戳跟数据库交互(凡是给数据库传输的时间戳都是long),数据库也会返回 long,完全不用管这个参数,只需要在客户端这边把这个long表达的意思理清楚就行。
CLI 打印时间
注意一下,我们刚才启动 CLI 的时候加了一个参数 -disableISO8601,这是干啥的?
这个参数的功能是 关闭 ISO 8601 格式打印,ISO 8601 是一种日期和时间的表示方法。
比如北京时间2021年5月21日下午2点22分22秒,ISO 8601 格式就是 :
2021-05-21T14:22:22+08:00
为啥要加这个呢,刚才我们查出来的数据时间是1和2,这是啥玩意,就很不好理解,大家还是喜欢看是哪年哪月哪天的。
所以,为了让CLI查出来的数据更直观,我们把这个 long 类型的时间戳,转成ISO8601格式的字符串来打印了。因此,不加任何参数启动CLI时,就是下面这种效果了。
这个时候,时间精度就开始发挥作用了。
时间戳与1970
时间戳是指格林威治时间1970年01月01日00时00分00秒到当前经过的时间。因此1970年01月01日00时00分00秒就是时间戳0。
更具体一点,0时间戳也是1970年01月01日00时00分00秒000毫秒000微秒000纳秒。
时间戳0没什么歧义,那1呢?是1970年01月01日00时00分01秒?还是00秒001毫秒?还是00秒000毫秒001微秒?亦或是00秒000毫秒000微秒001纳秒?
时间精度开始发挥作用
也就是这个1个时间单位,到底代表多长的时间,这就是时间精度要管的。
如果配置里的timestamp_precision =ms,那么1就表示1970年01月01日00时00分00秒001毫秒。
如果我们配置的是纳秒,那么写入的1打印出来的就是:
1970-01-01T08:00:00.000000001+08:00
总结一下:凡是涉及到整数的时间戳和字符串格式的日期的相互转换时,就是时间精度发挥作用的时刻。时间戳有负的吗,有的,1970年之前的时刻,比如1969年用时间戳表示就是小于0了。1970年只是坐标轴的原点,这个时间的坐标轴可正可负。只不过现在一般用不到负数了。
如果我们写入一个now(),在这时候系统内部就会使用 System.currentTime Millis() 获取当前ms级别的时间戳,一般就是这么一个16开头的13位的数字。
时间精度怎么改?
回到刚开始的启动问题,因为我们要对用户写入的时间戳的解释前后一致,比如刚开始配置的是ms,那么1就是ms,这时候改成ns,由于我们没有为每一个时间戳存储精度信息,这时候就会出现原本的1变成了 ns。修改前后打印出来的日期就不一致了。
为了避免这种情况,我们做了个启动检查,把 timestamp_precision 当做一个启动之后不能修改的配置项。
如果想改,正常情况我们推荐把data/system目录都清空,重新来过。
如果就想把老数据的时间格式改了,可以修改iotdb-engine.properties配置文件的同时,把data/system/schema/ system.properties 里的 timestamp_precision 也一起改了,这时候就没人能阻止你了。
好了,关于时间戳的介绍就到这里了。