我需要将时间戳类型设置为主键(在每种情况下它必须是唯一的,某些指令可以一次插入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)
)
但这不起作用。当我使用 pgAdmin3 检查时,它以毫秒精度写入。 当然,在同一毫秒内写入更多记录是可能的。 那么,我是否需要设置一些神秘的变量或其他东西,以便以微秒精度保存?
默认情况下,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);
错误:重复的键值违反了唯一约束“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 ... ;
如果将server
设置为默认使用 UTC 有意义,您可以将 postgresql.conf
中的时区参数设置为“UTC”。那么您就不必在每个会话中设置时区。
中看到的那样,使用 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)