我发生了一些混乱。 MySQL是否以秒为单位将TIMESTAMP
存储为unix时间,例如1541645714
还是以ISO 8601格式2018-11-08T02:55:14+00:00
我不确定为什么我总是认为后者只是输入格式,而MySQL将该格式转换为Unix时间。在我看来,这似乎更有效率。
有人可以帮我清理这个吗? TIMESTAMP
的实际存储方式是什么?我已经浏览了文档,似乎找不到任何答案。
感谢您的见解/帮助。
答案 0 :(得分:4)
TIMESTAMP
是4-byte integer,代表自UNIX时代以来的秒数(午夜1970-01-01
);在较新的版本中,它根据数据类型的fsp
(分数秒精度)参数而扩展为可以存储0到3字节的亚秒精度。
奖金:PostgreSQL有一个编译时参数,用于确定TIMESTAMP
是从2000-01-01
午夜起以秒数存储在8字节整数中还是以双精度浮点数存储。 (编辑:显然不再有更新的版本;感谢Basil Bourque)。
正如您所说,将时间戳存储为文本几乎没有效率。此外,weirdness of calendar从复杂跃升到了难以忍受的复杂程度。
请注意,以上内容约为TIMESTAMP
;其他日期/时间类型可能具有不同的表示形式。
答案 1 :(得分:2)
MySQL是否以秒为单位将TIMESTAMP存储为unix时间戳,例如1541645714
它是否实际上以ISO 8601格式存储2018-11-08T02:55:14 + 00:00
你不在乎。内部表示形式是与您的工作无关的实现细节。而且该实现可能会在将来的版本中更改。
数据库接受输入或生成输出的内容与其内部表示形式不直接相关。
您只需要关心the documented behavior,SQL标准以及它们之间的差异。
对于日期时间类型,SQL标准几乎没有涉及到主题,它定义了一些类型并且定义了很少的行为。因此,数据库的功能差异很大。
MySQL文档摘录:
TIMESTAMP数据类型用于包含日期和时间部分的值。 TIMESTAMP的UTC范围为'1970-01-01 00:00:01'至UTC'2038-01-19 03:14:07'。
MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,然后从UTC返回当前时区进行检索。
以微秒(6位数)精度表示的小数秒部分……被丢弃
如果您对实现感到好奇,请查看源代码。
但是,甚至没有看过源代码,在阅读了本文档之后,我们对TIMESTAMP
类型有两个线索:
因此我们知道类型可能存储为自纪元引用日期以来的32位整秒计数,在Unix和其他一些系统中通常使用:1970年UTC的第一时刻,1970年-01-01T00:00Z。这种32位计数将在该日期达到最大值,这在业界称为Y2038 Problem。
如果日期时间处理对您的项目很重要,则可以考虑使用具有更可靠的日期时间处理的数据库,例如Postgres。
您应该使用编程语言中的日期时间类型与数据库交换日期时间值。避免仅使用字符串进行通信。
在这方面处于业界领先地位的是Java 8及更高版本中的 java.time 框架,并具有适用于Java 6和7的反向端口。
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
Strin sql = "SELECT * FROM event_ WHERE when_ >= ? ;" ;
…
myPreparedStatement.setObject( 1 , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // In Postgres and some other databases, the offset-from-UTC will be zero, for UTC itself.
ZonedDateTime zdt = odt.atZoneSameInstant( ZoneId.of( "America/Montreal" ) ) ; // Adjust from UTC into a time zone. Same moment, same point on the timeline, different wall-clock time.
并证明我的观点……other Answer上的Amadan指出,我上面介绍的这份文档已经过时,它来自MySQL 5.5。在版本8中,实现确实发生了根本变化。