时间戳分辨率

jur*_*has 3 postgresql precision timestamp

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

  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)
)
Run Code Online (Sandbox Code Playgroud)

但这行不通。当我使用pgAdmin3进行检查时,它的写入精度始终为millisecs。当然,有可能在同一毫秒内写入更多记录。因此,是否需要设置一些错误的变量或其他内容以节省微秒的精度?

Mik*_*ll' 5

默认情况下,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);
Run Code Online (Sandbox Code Playgroud)
错误:重复的键值违反了唯一约束“ 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;
Run Code Online (Sandbox Code Playgroud)
Ť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 ... ;
Run Code Online (Sandbox Code Playgroud)

set time zone 'UTC';
insert ... ;
Run Code Online (Sandbox Code Playgroud)

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


Hou*_*ari 3

正如您在此处的文档中看到的那样,解决方案取决于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;
Run Code Online (Sandbox Code Playgroud)

结果:

date_part
-----------
      -100
(1 ligne)
Run Code Online (Sandbox Code Playgroud)