MySQL中DATETIME和TIMESTAMP核心区别在于:DATETIME原样存储、时区无关、范围大(1000–9999年)、占8字节;TIMESTAMP以UTC存储、读写自动时区转换、范围窄(1970–2038年)、占4字节且支持自动初始化与更新。

MySQL中存储时间,Datetime 和 Timestamp 是最常用的两种类型,但它们在行为、范围、时区处理和存储开销上存在关键差异。选错类型可能导致时区混乱、数据截断或意外自动更新,不能只看“都能存时间”就随意选用。
Datetime:精确按你输入的值存储,不主动参与时区转换
Datetime 存储的是“字面意义”的日期时间,比如你插入 '2024-05-20 14:30:00',它就原样存进去,读出来也一样。它不依赖系统时区,也不自动转换——无论服务器设成 UTC 还是 Asia/Shanghai,只要没手动转换,值不变。
- 范围大:支持从
'1000-01-01 00:00:00'到'9999-12-31 23:59:59' - 精度可选:支持微秒(如
DATETIME(6)),最多保留 6 位小数 - 默认不自动更新:除非显式定义
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,否则插入/更新时不会变 - 占用 8 字节(无精度)或更多(带微秒)
Timestamp:以 UTC 为中枢,读写时自动做时区换算
Timestamp 实际以 UTC 时间存储(占 4 字节),但你在客户端插入或查询时看到的,是根据当前会话时区(time_zone)自动转出的本地时间。比如你在上海(UTC+8)插入 '2024-05-20 14:30:00',MySQL 会把它转成 UTC(即 '2024-05-20 06:30:00')存入;查的时候再按你的时区转回来显示。
- 范围窄:仅支持
'1970-01-01 00:00:01'UTC 到'2038-01-19 03:14:07'UTC(经典“2038 问题”) - 自动初始化与更新:第一列
TIMESTAMP若未指定默认值,默认为CURRENT_TIMESTAMP;加上ON UPDATE CURRENT_TIMESTAMP后,每次更新行就会刷新 - 受全局/会话时区影响:同一条记录,在不同时区连接下查出来显示不同(但底层 UTC 值一致)
什么场景该用 Datetime?
适合记录“固定时刻”,且需要长期稳定、跨时区一致解读的时间点。
- 订单创建时间、文章发布时间、合同签署时间——这些是客观发生的事件,不应随查看者所在地变化而改变含义
- 需要超长跨度(早于 1970 或晚于 2038)的业务时间,比如历史档案、长期合约到期日
- 应用层已自行处理时区(如前端传 ISO 格式带偏移,后端统一转为 UTC 再存为 Datetime),数据库只做“透明容器”
什么场景该用 Timestamp?
适合记录“系统级操作时间”,尤其强调“现在发生了什么”,且希望数据库自动管理、轻量高效。
- 用户登录日志、记录最后修改时间(
updated_at),利用其自动更新特性减少应用代码干预 - 部署在多时区环境、但运维和开发人员习惯本地时间查看日志,靠自动转换降低理解成本
- 对存储空间敏感(单列省 4 字节),且业务时间全部落在 1970–2038 范围内
实际建议:优先用 Datetime,明确可控;仅当真需要 Timestamp 的自动行为或空间优势时才选用它。避免混用——同一张表里不要既有 Datetime 又有 Timestamp 来存同类语义的时间字段,容易引发隐式转换和维护困惑。











