What can I say!MySQL 的 DATETIME 和 TIMESTAMP 到底怎么选?

阅前提醒:这不是一篇枯燥的官方文档翻译,而是一篇帮你“避坑”的实战指南。


开篇:一个搞崩系统的“时区陷阱”

先问你一个问题:假如你的老板要求你把系统上线到海外,你信心满满地部署完,结果发现所有用户看到的时间都差了 8 个小时,你慌不慌?

这种场景我见过太多次了。绝大多数时候,锅都甩给了 MySQL 里的两个好兄弟:DATETIMETIMESTAMP

很多新手甚至是老手,在建表时都是随手选一个,觉得“反正都是存时间嘛”。但如果你不了解它们的底细,上面那个“时间错乱”的 Bug 早晚会找上门。

今天咱们就用大白话,一次性把这两个东西掰扯清楚。


一:核心差异

如果非要我用一句人话来总结它们的区别,那就是:

  • TIMESTAMP:像个“国际钟表”。它不管你在哪个国家,进去了先换算成伦敦时间(UTC)存着,等你查的时候,再根据你电脑的时区,换算成你当地的时间给你看。
  • DATETIME:像张“便签纸”。你写的是 2026-07-24 18:00:00,存进去就是这串数字,查出来还是这串数字。你说几点就是几点,绝不给你瞎翻译。

二:核心参数对比

当然,下面这几个硬指标你必须得看仔细了:

对比维度 TIMESTAMP DATETIME
存储空间 4 个字节(省地方) 5 个字节(5.6+版本,稍胖一点)
取值范围 小气得很:1970-01-012038-01-19 格局很大:1000-01-019999-12-31
时区影响 受影响(自动转换,成也萧何败也萧何) 不受影响(存储即永恒,铁面无私)
索引性能 稍快(因为存的是数字时间戳) 稍慢(但现代业务几乎感知不到)

敲黑板:看到 TIMESTAMP 的截止日期是 2038-01-19 了吗?这就是著名的 2038 年问题。如果你的系统打算活过 2038 年,用 TIMESTAMP 存那种百年大计的数据,到时候系统会直接报错崩溃。


三:什么时候用 TIMESTAMP 比较好?

既然 TIMESTAMP 有“2038 危机”,为什么还要用它?因为它有个绝活:自动处理时区

举个真实的例子:
假设你的公司开发了一个任务管理软件,北京的产品经理定了一个截止日期:2026-07-20 18:00:00

  • 如果用 TIMESTAMP:纽约的程序员打开网页,看到的时间会自动变成 2026-07-20 06:00:00你完全不需要在代码里写任何加减时差的逻辑,MySQL 自己就把换算做了。这对于做海外电商、跨国 SaaS 系统来说,简直是救命稻草。
  • 如果用 DATETIME:纽约哥们儿看到的也是 18:00:00,他会一脸懵,以为是下午 6 点,结果换算错时差,延误了上线进度。

所以,适合用 TIMESTAMP 的业务场景有:

  1. 全球化业务(用户遍布全球,需要看当地时间)。
  2. 日志记录create_time 这种,方便排查问题时统一查 UTC 时间)。
  3. 定时任务(依赖服务器系统时区触发)。

四:什么时候必须用 DATETIME?

如果你遇到以下情况,请务必将 TIMESTAMP 拉黑,只认 DATETIME

  1. 存生日(出生日期):比如 1990-01-01。如果你用 TIMESTAMP,万一服务器时区变了,某天你查数据发现同事的生日莫名其妙变成了前一天,这 bug 你修都修不好。
  2. 系统的“万年历”数据:比如保险到期日、合同生效日,这些时间有法律效力,不能因为时区改变而“抖动”。
  3. 业务涉及历史记录(跨越 2038 年):比如存储子孙后代的档案,必须用 DATETIME 熬过 2038 年。

最后建议

看到这里如果你还是不知道怎么选,直接抄下面的答案:

  • 新项目无脑首选 DATETIME。现在硬盘又不贵,不差那 1 个字节的空间,换来的是绝对的安全感和可控性。这是目前业界最稳妥的“政治正确”。
  • 只有明确需要“根据用户时区自动换算”时,才特意选用 TIMESTAMP。比如 App 的推送时间、消息的已读时间。

写在最后

记住一句话:TIMESTAMP 帮你做“翻译”,DATETIME 替你“做公证”。

希望读完这篇文章,你下次建表选时间类型时,能多一分笃定,少一分纠结。

你在实际开发中因为时区问题踩过坑吗?欢迎在评论区留言吐槽,分享你的“血泪史”!


(全文完)