MySQL 的 DATETIME 和 TIMESTAMP 到底怎么选?
What can I say!MySQL 的 DATETIME 和 TIMESTAMP 到底怎么选?
阅前提醒:这不是一篇枯燥的官方文档翻译,而是一篇帮你“避坑”的实战指南。
开篇:一个搞崩系统的“时区陷阱”
先问你一个问题:假如你的老板要求你把系统上线到海外,你信心满满地部署完,结果发现所有用户看到的时间都差了 8 个小时,你慌不慌?
这种场景我见过太多次了。绝大多数时候,锅都甩给了 MySQL 里的两个好兄弟:DATETIME 和 TIMESTAMP。
很多新手甚至是老手,在建表时都是随手选一个,觉得“反正都是存时间嘛”。但如果你不了解它们的底细,上面那个“时间错乱”的 Bug 早晚会找上门。
今天咱们就用大白话,一次性把这两个东西掰扯清楚。
一:核心差异
如果非要我用一句人话来总结它们的区别,那就是:
- TIMESTAMP:像个“国际钟表”。它不管你在哪个国家,进去了先换算成伦敦时间(UTC)存着,等你查的时候,再根据你电脑的时区,换算成你当地的时间给你看。
- DATETIME:像张“便签纸”。你写的是
2026-07-24 18:00:00,存进去就是这串数字,查出来还是这串数字。你说几点就是几点,绝不给你瞎翻译。
二:核心参数对比
当然,下面这几个硬指标你必须得看仔细了:
| 对比维度 | TIMESTAMP | DATETIME |
|---|---|---|
| 存储空间 | 4 个字节(省地方) | 5 个字节(5.6+版本,稍胖一点) |
| 取值范围 | 小气得很:1970-01-01 到 2038-01-19 | 格局很大:1000-01-01 到 9999-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 的业务场景有:
- 全球化业务(用户遍布全球,需要看当地时间)。
- 日志记录(
create_time这种,方便排查问题时统一查 UTC 时间)。 - 定时任务(依赖服务器系统时区触发)。
四:什么时候必须用 DATETIME?
如果你遇到以下情况,请务必将 TIMESTAMP 拉黑,只认 DATETIME:
- 存生日(出生日期):比如
1990-01-01。如果你用 TIMESTAMP,万一服务器时区变了,某天你查数据发现同事的生日莫名其妙变成了前一天,这 bug 你修都修不好。 - 系统的“万年历”数据:比如保险到期日、合同生效日,这些时间有法律效力,不能因为时区改变而“抖动”。
- 业务涉及历史记录(跨越 2038 年):比如存储子孙后代的档案,必须用 DATETIME 熬过 2038 年。
最后建议
看到这里如果你还是不知道怎么选,直接抄下面的答案:
- 新项目无脑首选
DATETIME。现在硬盘又不贵,不差那 1 个字节的空间,换来的是绝对的安全感和可控性。这是目前业界最稳妥的“政治正确”。 - 只有明确需要“根据用户时区自动换算”时,才特意选用
TIMESTAMP。比如 App 的推送时间、消息的已读时间。
写在最后
记住一句话:TIMESTAMP 帮你做“翻译”,DATETIME 替你“做公证”。
希望读完这篇文章,你下次建表选时间类型时,能多一分笃定,少一分纠结。
你在实际开发中因为时区问题踩过坑吗?欢迎在评论区留言吐槽,分享你的“血泪史”!
(全文完)
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Photon Yao - Notes
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果