MySQL created_at、updated_at 列是用 INT 还是 TIMESTAMP 来存储时间?
发布于 5 年前 作者 xuxu7 6071 次浏览 来自 问答

MySQL server 的时区和 Nodejs App 的不一样,不确定用哪种类型存储时间。 StackOverflow 上高票赞同 TIMESTAMP,但如果 App 和 MySQL 时区不一样,手动插入时间时会引起混乱:

// Node App 时区 +0800
// MySQL server 时区 UTC
const mysql = require('mysql');
const connection = mysql.createConnection();
const createdAt = new Date();
connection.query('INSERT INTO user(created_time) VALUES(?)', createdAt); // +0800
// connection.query('INSERT INTO user(created_time) VALUES(now())');     // +0000

user 表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_time` timestamp,
  PRIMARY KEY (`id`)
)

如果有人用 js new Date() 获取本地东8区时间,有人用 SQL函数 now() 获取0时区时间,插入数据时就会导致混乱。 大家觉得用什么好?

10 回复

mysql 无处不是坑。 timestamp 也有。

时间戳是没有时区的,你上面的代码并没有给出你这个created_time用的是什么类型,由于我已经有两年没用过sql了,但我猜测如果是TIMESTAMP类型,那么你插入数据库时无论用的什么方式,得到的最终都应该是一致的,也就是UTC时间戳 通常对时间的处理如果你用的是标准的date对象,是不需要关心时区的问题的,因为date对象最终会转换成时间戳去处理,而时间戳是没有时区的概念的, 所以为了避免混乱后端接口通常都是返回标准时间,最终显示给用户看的时间都由前端去处理

@zengming00TIMESTAMP 类型

谢谢您关于时区和 date 对象的解释。

那么你插入数据库时无论用的什么方式,得到的最终都应该是一致的,也就是UTC时间戳

按我的理解,假如 App 当前时间是 2019-08-29 15:00:00 GMT+0800

  • 使用 js new Date() 方式,会插入 2019-08-29 15:00:00,mysql 转化为时间戳 1567062000 存储
  • 使用 sql now() 函数方式,会插入 2019-08-29 07:00:00,mysql 转化为时间戳 1567033200 存储

所以会混乱,不知我的理解是否正确。

@xuxu7 如果时间字符串不带时区,那就会有问题

使用 js new Date() 方式,会插入 2019-08-29 15:00:00,mysql 转化为时间戳 1567062000 存储 使用 sql now() 函数方式,会插入 2019-08-29 07:00:00,mysql 转化为时间戳 1567033200 存储

像这样的才是带时区的字符串 "2019-08-29T10:35:04.137Z" “2019-06-25T15:00:00.000+08:00”

嗯,如果能带时区问题就解决了。 目前 MySQL TIMESTAMP/DATETIME 不接受时区,可接受的格式是 YYYY-MM-DD hh:mm:ssYYYYMMDDhhmmss

别怀疑,INT是唯一跨越语言、数据库、操作系统的

首先时间戳是一个差值,无关时区,一般设置mysql默认时区或者设置连接参数,还有你可以convert_tz转化到目标时区

你可以先试下设置连接参数能不能解决你的问题

另外不建议用now(), 建议使用CURRENT_TIMESTAMP()

回到顶部