NOW()和CURRENT_TIMESTAMP()在MySQL中功能相似但不完全等价:前者是MySQL专有别名,后者符合SQL标准;语法、默认值定义、自动更新、精度支持及时区行为均有差异。

MySQL 里 NOW() 和 CURRENT_TIMESTAMP() 真的等价吗?
绝大多数情况下,它们返回相同结果,但不是“完全等价”——CURRENT_TIMESTAMP() 是标准 SQL 的写法,而 NOW() 是 MySQL 的别名函数;在严格模式或跨数据库迁移时,用 CURRENT_TIMESTAMP() 更稳妥。
常见错误现象:INSERT INTO log (ts) VALUES (NOW);(漏了括号)→ 报错 ERROR 1064;MySQL 把没括号的 NOW 当作列名或标识符处理,必须写成 NOW() 或 CURRENT_TIMESTAMP()。
- 两者都返回当前会话时区下的时间戳(精度到秒,除非显式声明毫秒)
- 作为默认值定义字段时,
CURRENT_TIMESTAMP(无括号)是合法语法,NOW()则不被允许 - 如果需要自动更新时间,只能用
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,NOW()不支持该语法
想带毫秒?别只写 CURRENT_TIMESTAMP()
默认调用不带精度参数时,CURRENT_TIMESTAMP() 和 NOW() 都只返回秒级时间,比如 2024-05-22 14:30:45。要毫秒,必须显式指定精度。
使用场景:日志追踪、高并发幂等判断、调试时需区分快速连续操作。
-
CURRENT_TIMESTAMP(3)→ 返回带 3 位毫秒的时间,如2024-05-22 14:30:45.123 -
NOW(6)→ 同样有效,支持最多 6 位微秒,但注意:底层存储类型得是DATETIME(6)或TIMESTAMP(6),否则精度被截断 - 性能影响极小,但字段定义精度越高,索引体积略增,写入时多一次截断/舍入计算
时区搞错导致时间“凭空偏移”?查 @@time_zone 比猜强
你看到的 NOW() 结果,取决于会话时区,不是服务器系统时区。很多线上问题就卡在这儿:应用连的是 UTC 时区的实例,但开发本地连的是 +08:00,同一句 SQL 返回值差 8 小时。
错误现象:定时任务在凌晨 2 点触发失败,日志里查 NOW() 却显示是凌晨 10 点。
- 执行
SELECT @@time_zone;查当前会话时区(常见值:SYSTEM、+00:00、Asia/Shanghai) - 临时修改会话时区:
SET time_zone = '+08:00';,之后NOW()才按东八区算 - 建表时若用
TIMESTAMP类型,值会自动按会话时区转存/读取;DATETIME则原样存储,不转换——这点常被忽略
在 INSERT 或 DEFAULT 中直接用 CURRENT_TIMESTAMP 要小心括号
这是最易踩的语法坑:在列定义里写默认值,CURRENT_TIMESTAMP 可以不带括号;但一旦加了括号,MySQL 5.6+ 会报错 ERROR 1067: Invalid default value。
示例对比:
CREATE TABLE events ( id INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- ✅ 合法 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- ✅ 合法 bad_col TIMESTAMP DEFAULT CURRENT_TIMESTAMP() -- ❌ 报错 );
-
NOW()在 DEFAULT 子句中完全不被支持,哪怕带括号也不行 - 如果要用函数式默认值(比如加上偏移),得改用触发器或应用层生成
- MySQL 8.0+ 支持表达式默认值,但仅限确定性函数,
NOW()仍被排除在外
时区设置、精度声明、括号有无、字段类型选择——这四点任意一个配错,NOW() 和 CURRENT_TIMESTAMP() 就可能给你“惊喜”。










