【发布时间】:2012-08-01 16:55:24
【问题描述】:
unix 时间戳的 PostgreSQL 字段类型:
- 将其存储为 unix 时间戳
- 也可以将其检索为 unix 时间戳。
已通过Date/Time Types postgreSQL V 9.1。
- 整数是最好的方法吗!? (这是我在使用 MySQL 时所做的。曾经使用过
int(10))
【问题讨论】:
unix 时间戳的 PostgreSQL 字段类型:
已通过Date/Time Types postgreSQL V 9.1。
int(10))【问题讨论】:
现在 (2014-04-09) 的 unix 纪元时间戳是 1397071518。所以我们需要一种能够存储至少这么大的数字的数据类型。
有哪些数据类型可用?
如果您参考 PostgreSQL documentation on numeric types,您会发现以下选项:
Name Size Minimum Maximum
smallint 2 bytes -32768 +32767
integer 4 bytes -2147483648 +2147483647
bigint 8 bytes -9223372036854775808 +9223372036854775807
这在时间表示方面意味着什么?
现在,我们可以使用epoch converter 将这些数字转换为日期:
Name Size Minimum Date Maximum Date
smallint 2 bytes 1969-12-31 1970-01-01
integer 4 bytes 1901-12-13 2038-01-18
bigint 8 bytes -292275055-05-16 292278994-08-17
请注意,在最后一个例子中,使用秒数会让您深入过去和未来,这可能无关紧要。我给出的结果是,如果您以毫秒为单位表示 unix 纪元。
那么,我们学到了什么?
smallint 显然是个糟糕的选择。integer 目前是一个不错的选择,但您的软件将在 2038 年爆发。Y2K 启示录在 Year 2038 Problem 上没有任何内容。bigint 是最好的选择。这是面向未来的,可以满足大多数可以想象的人类需求,尽管the Doctor 可能仍然是criticise。您可能会也可能不会考虑是否最好将时间戳存储为另一种格式,例如ISO 8601 标准。
【讨论】:
我会使用 TIMESTAMP WITH(OUT) TIME ZONE 并在需要时使用 EXTRACT 来获取 UNIX 时间戳表示。
比较
SELECT NOW();
与
SELECT EXTRACT(EPOCH FROM NOW());
【讨论】:
unix timestamp?
TIMESTAMP WITH(OUT) TIME ZONE 不存储文字时间戳。
TIMESTAMP WITH TIME ZONE 存储为 UTC 2000 年 1 月 1 日午夜开始的微秒的 64 位整数(忽略闰秒,因此更像 UT1)。这可以快速轻松地转换为 Unix 时间,同时允许简单的演示和日期数学。如果您真的想要更粗略的分辨率、整数表示和日期计算的难度,请随意使用 bigint 或 numeric。净赢的情况并不多,但也许你就是其中之一。
整数会很好,但不够好,因为 postgresql 不支持无符号类型
【讨论】: