我需要将主键设置为时间戳类型(在每种情况下它必须是唯一的,某些指令可以在时间插入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检查时,它以毫秒精度写入。 当然,可以在相同的毫秒内写入更多记录。 那么,我是否需要设置一些神奇的变量或其他东西,以便以微精度保存?
答案 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)