项目中mysql date_time四舍五入问题
目录
背景
项目中向插入消息中心服务发送数据,消息字符串中有时间,格式是2006-01-02 15:04:05,于此同时向mysql数据库写数据,其中有字段create_time字段类型为date_time。发现有偶然消息中的时间和数据库的时间不一致的情况,数据库会慢一秒。 抽象一下场景,作为复现的步骤: 新建一个数据表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`create_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
代码示例
func main() {
err := mysqlconn.InitDb()
if err != nil {
fmt.Println(err)
return
}
db, err := mysqlconn.GetDb()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(db)
now := time.Now()
// 打印2023-10-29 16:40:45.759
fmt.Println(now.Format("2006-01-02 15:04:05.000"))
//打印2023-10-29 16:40:45
fmt.Println(now.Format("2006-01-02 15:04:05"))
u := User{
CreateTime: now,
}
// 打印INSERT INTO `user` (`create_time`) VALUES ("2023-10-29 16:40:45.759")
err = db.Create(&u).Error
if err != nil {
fmt.Println(err)
return
}
}
四舍五入
经观察上方代码打印日志,并没有什么不妥,但是查询数据却发现 数据库里面是2023-10-29 08:40:46,慢了一秒。
原来是毫秒大于等于500就会自动四舍五入。
解决方案
第一种解决方案就是设置精度
alter table user change create_time create_time datetime(3) NOT NULL DEFAULT '1970-01-01 00:00:00';
这样插入的数据是2023-10-29 08:52:51.510
第二种解决方案就是golang的时间去掉毫秒
now := time.Now().Truncate(time.Second)
第三种比较直接,但是个人最喜欢,就是项目中存储时间都用bigint存时间戳