时间戳分辨率

时间:2014-11-19 21:14:37

标签: postgresql timestamp precision

我需要将主键设置为时间戳类型(在每种情况下它必须是唯一的,某些指令可以在时间插入k条记录),默认值为“current_timestamp”。它是一种日志文件。要做到这一点,我应该将时间戳分辨率提高到微秒(我认为pg不可能在一秒内写出一百万条记录)。这种精确度可以用于postgres。See here它是这样的:

  CREATE TABLE upsistema
(
  t timestamp(6) without time zone NOT NULL DEFAULT current_timestamp(6) without time zone,
  blabla bigint,
  foo bigint,
  CONSTRAINT "XIDS3w" PRIMARY KEY (t)
)

但它不起作用。当我用pgAdmin3检查时,它以毫秒精度写入。 当然,可以在相同的毫秒内写入更多记录。 那么,我是否需要设置一些神奇的变量或其他东西,以便以微精度保存?

2 个答案:

答案 0 :(得分:4)

默认情况下,PostgreSQL以最大可能的精度存储时间戳。

如果我在你的鞋子里,我可能会使用不同的默认值来表示时间戳。 current_timestamp的值是当前事务开始的时间。无论您插入多少行,无论需要多长时间,它都不会在执行事务期间发生变化。这意味着由于重复的主键值,INSERT语句可能会失败。

create table upsistema (
  t timestamp without time zone primary key
    default current_timestamp,
  foo bigint
);
insert into upsistema (foo) values (42), (43), (44);
ERROR:  duplicate key value violates unique constraint "upsistema_pkey"

请尝试使用clock_timestamp()作为默认值。这并不能保证成功,但确实更有可能。

create table upsistema (
  t timestamp without time zone primary key
    default clock_timestamp(),
  foo bigint
);
insert into upsistema (foo) values (42), (43), (44);

select * from upsistema;
t                              foo
--
2014-11-19 19:17:23.369432     42
2014-11-19 19:17:23.36958      43
2014-11-19 19:17:23.369587     44

要绝对保证成功,请更改主键约束,或完全删除它。这是否有意义依赖于应用程序,但我会惊讶地发现多个客户端以相同的微秒记录数据。

您的表使用timestamp without time zone,但current_timestamp和clock_timestamp()返回timestamp with time zone。在运行SQL语句之前,最好将会话的时区更改为UTC。

set time zone 'UTC';
select ... ;

set time zone 'UTC';
insert ... ;

如果将服务器设置为默认使用UTC是有意义的,您可以将postgresql.conf中的timezone参数设置为' UTC'。然后,您不必在每个会话中设置时区。

答案 1 :(得分:1)

正如您在文档here中看到的那样,使用microseconds类型的分辨率最高可达timestamp

以下示例显示微秒存在:

CREATE TABLE table_test
(
  column1 timestamp(6) without time zone,
  column2 timestamp(6) without time zone
);

insert into table_test (column1,column2) values (current_timestamp, current_timestamp + interval '100 MICROSECONDS');

select  extract (MICROSECONDS  from column1 - column2 ) from table_test;

结果:

date_part
-----------
      -100
(1 ligne)