mysql中now()与current_timestamp()完全等价,行为、类型、实现均相同;推荐统一加括号以避免语法混淆,建表默认值常用current_timestamp(不带括号)符合sql标准。

MySQL里用NOW()还是CURRENT_TIMESTAMP()?
两者在MySQL中完全等价,返回值、类型、行为一模一样——连函数签名都共享同一个实现。官方文档也明确说CURRENT_TIMESTAMP()是NOW()的同义词。
实际写法上,带括号和不带括号(如CURRENT_TIMESTAMP)在MySQL里也都合法,但建议统一加括号,避免和列名或默认约束语法混淆。
- 如果在
CREATE TABLE里设默认值,用CURRENT_TIMESTAMP(不带括号)更常见,这是SQL标准写法 - 在
SELECT或INSERT语句里,NOW()和CURRENT_TIMESTAMP()可互换,选哪个纯看团队习惯 - 注意:MySQL 5.6.5+才支持
CURRENT_TIMESTAMP作为DATETIME列的默认值;老版本只认TIMESTAMP类型
PostgreSQL里不能直接用NOW()当默认值?
PostgreSQL中NOW()是函数,必须加括号;而CURRENT_TIMESTAMP是“伪常量”(pseudo-constant),不带括号也能用,且在DDL中更稳妥。
比如建表时写created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP没问题,但写成DEFAULT NOW会报错:ERROR: function now() does not exist(少括号);写成DEFAULT NOW()虽能过,但某些ORM或迁移工具可能解析异常。
-
CURRENT_TIMESTAMP在PG里还支持精度参数,如CURRENT_TIMESTAMP(3)表示毫秒级 -
NOW()不支持精度参数,强行加会报错:ERROR: function now(integer) does not exist - PG中
CURRENT_TIMESTAMP和clock_timestamp()有本质区别:前者在事务开始时就固定,后者每次调用都实时取系统时间
跨数据库移植时最危险的坑
看似一样的写法,在不同数据库里语义可能完全不同。比如CURRENT_TIMESTAMP在MySQL里允许用于DATETIME列默认值,但在SQLite里它只是字符串字面量,不会自动转成时间戳;而在SQL Server里,CURRENT_TIMESTAMP是GETDATE()的别名,但NOW()根本不存在。
- SQLite只认
datetime('now')或strftime('%Y-%m-%d %H:%M:%S', 'now'),写NOW()直接报no such function: NOW - SQL Server中
CURRENT_TIMESTAMP可用,但它是DATETIME类型,精度只到3.33ms,不如SYSDATETIME()精确 - 如果用JDBC或ORM做多库适配,别硬写SQL函数,优先走驱动层提供的时间绑定(如
PreparedStatement.setTimestamp())
为什么有时候NOW()返回的时间比系统慢几秒?
这不是函数本身的问题,而是MySQL的system_time_zone和time_zone变量没对齐。比如服务器系统时区是UTC+8,但MySQL全局time_zone设成了SYSTEM,而system_time_zone又因为历史原因读错了——结果NOW()返回的是错误偏移下的时间。
- 查当前设置:
SELECT @@global.time_zone, @@session.time_zone, @@system_time_zone; - 临时修复:
SET time_zone = '+08:00';,但重启后失效 - 永久修复:改
my.cnf里的default-time-zone = '+08:00',并确保系统/etc/timezone或timedatectl设置正确 - 注意:修改后已有
TIMESTAMP列数据不会重算,只影响新插入或函数调用结果
时区问题永远是最隐蔽的那层灰,尤其在容器或云环境里,宿主机、OS、数据库配置三层时区稍有不一致,NOW()就变成“薛定谔的时间”。










