MySQL中NOW()与CURRENT_TIMESTAMP完全等价,均返回会话开始时的时间戳快照;NOW()更简洁常用,CURRENT_TIMESTAMP符合SQL标准且支持DDL默认值,二者均受会话时区影响。

MySQL里用NOW()还是CURRENT_TIMESTAMP?效果一样
在MySQL中,NOW()和CURRENT_TIMESTAMP(或带括号的CURRENT_TIMESTAMP())完全等价,都返回当前会话开始时的时间戳(即语句执行时刻的datetime值),精度默认到秒。它们不是实时滚动的“时钟”,而是一次性快照。
常见错误是以为CURRENT_TIMESTAMP在INSERT中会随每行插入动态更新——其实只要没显式声明为列的默认值或ON UPDATE触发,它就只在语句执行时求值一次。
-
NOW()是MySQL专有函数,更短、更常用,可读性略高 -
CURRENT_TIMESTAMP是SQL标准写法,跨数据库兼容性稍好(PostgreSQL/SQLite也支持,但行为细节可能不同) - 二者都受会话时区影响:
SET time_zone = '+08:00'之后再调用,结果就是东八区时间
PostgreSQL中必须用CURRENT_TIMESTAMP,NOW()只是别名
PostgreSQL不认NOW()为独立函数,它只是CURRENT_TIMESTAMP的同义词。调用NOW()实际走的是CURRENT_TIMESTAMP的实现路径,行为完全一致。
但要注意:PostgreSQL的CURRENT_TIMESTAMP默认带6位微秒精度(如2024-05-12 14:23:08.123456),而MySQL默认只有秒级。如果应用依赖毫秒级时间做排序或去重,这个差异会导致问题。
- 要截断精度,可用
CURRENT_TIMESTAMP(3)获取毫秒级(PostgreSQL) - MySQL中想加毫秒需写
NOW(3)(5.6.4+支持) - 跨库迁移时,若原SQL写
NOW(),迁到PostgreSQL没问题;但若用NOW(3),PostgreSQL会报错,得改成CURRENT_TIMESTAMP(3)
作为列默认值时,CURRENT_TIMESTAMP能自动更新,NOW()不能直接用
在MySQL建表时,只有CURRENT_TIMESTAMP(不带括号)能被接受为DEFAULT或ON UPDATE子句的值;NOW()会报语法错误。
CREATE TABLE logs ( id INT PRIMARY KEY, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
上面写法合法;但如果把CURRENT_TIMESTAMP换成NOW(),MySQL会提示Invalid default value for 'created_at'。
- 这是语法限制,不是功能差异——
NOW()本身无法在DDL中充当默认值表达式 - PostgreSQL同样只允许
CURRENT_TIMESTAMP用于列默认值,NOW()在此处无效 - 想让更新时间自动刷新,MySQL必须显式写
ON UPDATE CURRENT_TIMESTAMP;PostgreSQL需配合TRIGGER或用GENERATED ALWAYS AS(12+)
时区混乱时,NOW()和CURRENT_TIMESTAMP都不可信
如果数据库服务器系统时区、MySQL全局时区、会话时区三者不一致,NOW()返回的结果可能和你预期的“本地时间”对不上。比如服务器设为UTC,但应用期望返回北京时间,而会话没执行SET time_zone = '+08:00',那所有NOW()结果都会偏移8小时。
- 查当前会话时区:
SELECT @@session.time_zone; - 查全局时区:
SELECT @@global.time_zone; - 临时修改会话时区:
SET time_zone = '+08:00';(注意:仅对当前连接有效) - 生产环境建议统一用UTC存时间,应用层负责格式化显示——避免靠
NOW()“猜”用户本地时间
真正容易被忽略的是:这些函数返回的是服务端时间,不是客户端时间。前端JavaScript的Date.now()和数据库的NOW()之间天然存在网络延迟与系统时钟偏差,做精确时间比对(比如生成唯一有序ID)时,不能直接混用。

















