目录

项目中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存时间戳