postgresql - PostgreSQL 如何在内部存储日期时间类型

标签 postgresql timestamp storage

在阅读 PostreSQL (13) 文档时,我遇到了 this页面,其中列出了不同日期时间类型的存储大小。

除其他外,它指出:

Name                         Storage Size       Description                                   Low Value      High Value      Resolution
----                         ------------       -----------                                   ---------      ----------      ----------
timestamp without time zone       8 bytes       both date and time (no time zone)               4713 BC       294276 AD   1 microsecond
timestamp with time zone          8 bytes       both date and time, with time zone              4713 BC       294276 AD   1 microsecond
time with time zone              12 bytes       time of day (no date), with time zone     00:00:00+1559   24:00:00-1559   1 microsecond

timestamp without time zone我能理解:低值和高值之间大概有(4713 + 294276) * 365 * 24 * 60 * 60 * 1000000 微秒。 (不考虑日历更改等)。这相当于大约 2^63 个值,这些值可以存储在 8 个字节中。

但是,timestamp with timezone 具有相同的范围和分辨率,并且可以额外存储时区信息。如果我们已经使用 63 位作为值,则只剩下一位,这不足以存储时区,因此内部存储的工作方式必须有所不同。

更奇怪的是,虽然时间戳仅使用 8 个字节,但 time with time zone 需要 12 个字节,尽管它具有相同的分辨率和更小的允许值范围。

因此我的问题是:PostgreSQL 中这些类型的内部存储是如何工作的?

最佳答案

timestamp with time zonetimestamp without time zone 都存储为一个 8 字节整数,表示自 2000 年 1 月 1 日午夜以来的微秒数。

不同之处在于,timestamp with time zone 被解释为 UTC,并根据显示的 timezone 参数的当前设置进行转换。

定义在src/include/datatype/timestamp.h中:

typedef int64 Timestamp;
typedef int64 TimestampTz;

time without time zone 是一个 8 字节整数,表示自午夜以来的微秒数(4 字节整数是不够的)。参见 src/include/utils/date.h:

typedef int64 TimeADT;

time with time zone 有一个额外的 4 字节整数,表示以秒为单位的时区偏移量。

参见src/include/utils/date.h:

typedef struct
{
    TimeADT     time;           /* all time units other than months and years */
    int32       zone;           /* numeric time zone, in seconds */
} TimeTzADT;

关注the documentation并避免 time with time zone:

The type time with time zone is defined by the SQL standard, but the definition exhibits properties which lead to questionable usefulness.

关于postgresql - PostgreSQL 如何在内部存储日期时间类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65143816/

相关文章:

ruby-on-rails - 更新 Rails 4 和 PostgreSQL json 列中的单个键/值对?

android - Acer Iconia A200 上的 VideoView getCurrentPosition() 异常

c# - Windows 8 中的文件 IO

c++ - .bss 部分零初始化变量是否占用 elf 文件中的空间?

c# - 将数据从文本框插入到 Postgresql

postgresql - 在给定的 createAt 日期后获取数据

使用默认值更新 Hibernate

python - RTSP 视频流的发送方报告 (SR) 的绝对时间戳

html - 使用链接在HTML5音频播放器上设置currenttime

python - python中的安全凭证存储