You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中Datetime与Timestamp哪种类型更适合存储时间点信息?

引言

我知道此前已有类似问题被提出,但针对我的使用场景仍需进一步测试,且测试结果让我有些惊讶和困惑。以下是测试过程(含代码)及结果说明。

我正在开发的应用具备以下特性:

  • 记录事件历史(某一时间点发生的事件):
    • 历史记录不可变,一旦写入便不再修改;
    • 需基于该历史记录生成报表。
  • 调度未来的可重复任务,例如“每周五执行该检查”。

因此,准确理解时间数据至关重要。我正尝试了解MySQL中的Timestamp和Datetime类型,以及它们与Java代码、ISO8601时间字符串的交互方式。

我查阅了MySQL官方文档中关于Timestamp类型的说明:它会将时间值转换为UTC存储,检索时再转换为服务器或会话时区,这听起来很适合时间点存储。

而Datetime类型的机制相对模糊,有文章认为它与字符串差异不大,我执行SELECT NOW() + 0;查询后得到了与文章一致的结果。

为理清疑问,我编写了一个小型Java类,向包含以下三列的数据库表写入数据:

  • tz(表示标准时区ID的字符串,测试中使用了UTC,但它并非时区);
  • mydatetime(Datetime类型列);
  • mytimestamp(Timestamp类型列)。

Java代码

我编写的Java代码已上传至代码托管平台,核心逻辑是处理不同时区的ISO8601时间字符串,完成写入MySQL表并读取验证的流程。

测试1

我生成了3个不同的ISO8601时间字符串,它们指向同一时间点但对应不同时区/偏移量,将其写入数据库后再检索并打印。初始时MySQL服务器时区设置为+00:00。

输出结果

写入数据库的时间:

UTC 2018-04-13T11:12:00Z, 1523617920 
Europe/Amsterdam 2018-04-13T13:12:00+02:00, 1523617920 
Asia/Calcutta 2018-04-13T16:42:00+05:30, 1523617920 

从数据库读取的存储时间:

Description, Datetime column (epoch seconds), Datetime column (as ISO string), Timestamp column (as epoch seconds), Timestamp column (as ISO string) 
UTC, 1523617920, 2018-04-13T11:12:00Z, 1523617920, 2018-04-13T11:12:00Z 
Europe/Amsterdam, 1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam], 1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam] 
Asia/Calcutta, 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta], 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta] 

所有结果均正常,将epoch seconds转换后,与ISO8601时间字符串完全一致。

测试2

随后我将MySQL服务器时区从UTC(+00:00)改为Europe/Amsterdam(+02:00),再次读取存储的时间。

输出结果

从数据库读取的存储时间:

Description, Datetime column (epoch seconds), Datetime column (as ISO string), Timestamp column (as epoch seconds), Timestamp column (as ISO string) 
UTC, 1523617920, 2018-04-13T11:12:00Z, 1523625120, 2018-04-13T13:12:00Z 
Europe/Amsterdam, 1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam], 1523625120, 2018-04-13T15:12+02:00[Europe/Amsterdam] 
Asia/Calcutta, 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta], 1523625120, 2018-04-13T18:42+05:30[Asia/Calcutta] 

我原本以为Datetime列会受影响(因为它不存储时区信息),但实际变化的却是Timestamp列——它的epoch seconds和ISO字符串都发生了偏移,而Datetime列完全保留了写入时的原始信息。

结论与疑问

我们不会频繁更改服务器时区,我希望找到能准确、稳定表示时间点的MySQL数据类型。根据上述测试,若以ISO8601字符串形式传入时间点信息,Datetime类型能保留原始信息,不受服务器时区变更的影响;而Timestamp则会随服务器时区变化自动转换,导致读取的时间值发生偏移。

不过我不确定我的测试代码或结果解读是否存在错误,想请教各位:在我的测试场景(需要存储不可变的时间点、生成报表、调度任务)中,MySQL的Datetime类型是否更适合存储时间点信息?

内容的提问来源于stack exchange,提问作者Eoin McCarthy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:24:59