如何最好地在PostgreSQL中存储时间戳?


20

我正在研究PostgreSQL数据库设计,我想知道如何最好地存储时间戳。

假设条件

不同时区的用户将数据库用于所有CRUD功能。

我看了两个选项:

  • timestamp NOT NULL DEFAULT (now() AT TIME ZONE 'UTC')

  • bigint NOT NULL DEFAULT

因为timestamp我会发送一个字符串,该字符串代表INSERT时刻的确切(UTC)时间戳。

因为bigint我会以数字格式存储完全相同的内容。(时区问题是在将毫秒移交给服务器之前处理的,因此始终在UTC中使用毫秒。)

存储a的一个主要优点bigint是可以更容易存储和检索,因为传递正确格式的时间戳比简单的数字(自Unix Epoc以来的毫秒数)要复杂得多。

我的问题是,哪种方法可以进行最灵活的设计,以及每种方法的陷阱是什么?


出于多种原因,时间戳在表示时间戳方面要优于bigint。我想不出为什么bigint比时间戳更好的单一原因。
Lennart

我认为BigInt可以更容易的主要原因是,它可能更容易检索和存储。我将更新我的问题。
2015年

Answers:


23

由于要处理多个时区timestamp,因此将时间戳记存储为或timestamptztimestamp with time zone)。这会强制执行有效数据,通常效率最高。一定要了解数据类型,周围会有一些误解:

为解决您的问题:

传递正确格式的时间戳比简单的数字复杂

如果您愿意,可以通过两种方式传递和检索UNIX纪元:

SELECT to_timestamp(1437346800)
     , extract(epoch FROM timestamptz '2015-07-20 01:00+02');

有关:

如果要通过写入数据库存储当前时间戳记,请使用timestamptz 具有默认值now()。通常,DB服务器上的系统时间比多个客户端提交各自时间的概念要可靠和一致得多。
因为INSERT它可以很简单:

CREATE TABLE foo (
  ... -- other columns
, created_at timestamptz NOT NULL DEFAULT now()
);

而且只是不要写那一栏。它是自动填写的。


这使事情很清楚。除了将时间戳存储为8字节整数这一事实外,与与bigint进行存储相同,使用“ to_timestamp”函数进行存储和检索使得此选择更为简单。谢谢
Bam 2015年

8

您应该始终将数据存储在其本机数据类型中,以便可以使用内置函数。时间戳记的数据类型显然是timestamp

顺便说一句,一个timestamp存储为一个字符串,它存储为8字节整数,完全一样bigintPostgreSQL文档


抱歉,我要说的是我将发送一个字符串用于存储,而不是存储时间戳。更正它。
Bam 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.