MySQL中TIMESTAMP字段自动设为当前时间需用DEFAULT CURRENT_TIMESTAMP,仅此函数合法;多字段时须显式声明,且受版本及时区影响。

MySQL 中 TIMESTAMP 字段如何自动设为当前时间
直接用 TIMESTAMP 类型配合 CURRENT_TIMESTAMP 默认值就能实现,但必须注意:只有第一个 TIMESTAMP 字段能用 CURRENT_TIMESTAMP 作默认值(MySQL 5.6.5 之前),新版本放宽了限制,但仍需显式声明。
常见错误是写成 DEFAULT NOW() 或 DEFAULT SYSDATE() —— 这些在 DDL 里不被接受,只有 CURRENT_TIMESTAMP(及其简写 CURRENT_TIMESTAMP())是合法的默认表达式。
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP✅ -
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP✅(MySQL 5.6.5+ 支持多TIMESTAMP自动更新) -
created_at TIMESTAMP DEFAULT NOW()❌ 报错:Invalid default value for 'created_at' - 定义两个
TIMESTAMP都带DEFAULT CURRENT_TIMESTAMP,但没加ON UPDATE—— 第二个会静默转为0000-00-00 00:00:00或报错,取决于 SQL mode
为什么不用 DATETIME 配 CURRENT_TIME
CURRENT_TIME 是时间部分(HH:MM:SS),不能用于给 DATETIME 或 TIMESTAMP 字段设默认值;它只在运行时表达式中有效,比如 SELECT CURRENT_TIME。DDL 中设默认值必须用 CURRENT_TIMESTAMP。
DATETIME 本身不支持函数作为默认值(MySQL 5.6.5 之前完全不支持,默认值只能是常量;8.0.13+ 才支持 DEFAULT CURRENT_TIMESTAMP 用于 DATETIME,但需显式启用 explicit_defaults_for_timestamp=OFF 且行为和 TIMESTAMP 不同)。
-
DATETIME DEFAULT CURRENT_TIMESTAMP在 MySQL 8.0.13+ 可用,但不会自动更新(ON UPDATE不生效) -
TIMESTAMP字段受时区影响,存的是 UTC,查出来转成本地时区;DATETIME是“所见即所得”,存啥查啥 - 如果业务要求严格按服务器本地时间记录、且不涉及时区转换,
DATETIME+ 应用层写入更可控
ON UPDATE CURRENT_TIMESTAMP 的实际表现
这个子句会让字段在每次 UPDATE 行时自动刷新为当前时间,但仅限于该字段未在 UPDATE 语句中被显式赋值 —— 即使赋的是 NULL 或旧值,也会触发更新。
容易忽略的点:如果表里有多个带 ON UPDATE CURRENT_TIMESTAMP 的 TIMESTAMP 字段,只有第一个定义的会生效(旧版本),新版本(5.6.5+)允许多个,但必须全部显式写出完整定义,不能省略括号。
-
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP✅ -
updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP❌ 没设默认值,插入时为NULL(若字段允许 NULL)或报错 -
UPDATE t SET name='x' WHERE id=1→updated_at自动更新 -
UPDATE t SET name='x', updated_at=updated_at WHERE id=1→updated_at不更新(显式赋值了)
时区与初始化值的坑
TIMESTAMP 默认使用系统时区(system_time_zone),但存储时转为 UTC,查询时再转回。如果应用部署在不同时区的服务器上,而你又依赖默认值做时间比较,结果可能和预期不符。
另一个典型问题:建表时没设 DEFAULT CURRENT_TIMESTAMP,只写了 TIMESTAMP,MySQL 会隐式加上 DEFAULT CURRENT_TIMESTAMP(当 explicit_defaults_for_timestamp=OFF,这是老版本默认行为)。这会导致迁移或复制环境出问题。
- 检查当前行为:
SELECT @@explicit_defaults_for_timestamp,返回OFF表示隐式规则生效 - 安全做法:所有
TIMESTAMP字段都显式写全DEFAULT和ON UPDATE,不依赖隐式逻辑 - 跨时区服务建议统一用 UTC 存储,应用层处理展示时区,避免靠数据库自动转换
SHOW CREATE TABLE 确认字段定义是否如你所写,而不是你以为的那样。


















