数据库时区和timestamp

问题:迁移后时间变了。

迁移前数据

在这里插入图片描述

迁移后数据

在这里插入图片描述

查看时区

show VARIABLES like '%time_zone%';

迁移前时区

在这里插入图片描述

迁移后时区

在这里插入图片描述

这是什么意思?

首先time_zone显示的是当前数据库设置的时区,然后system_time_zone顾名思义就是数据库所在系统的时区,而当time_zone的值是system(默认)的时候,代表我们mysql数据库使用系统时区。

那有什么影响?

时区的变化,影响的必然就是时间了,而在mysql中,我们存储时间的方式主要是四种;

  1. 使用mysql的datetime数据类型进行存储
  2. 使用timestamp数据类型进行存储
  3. 将时间直接转成时间戳,然后在数据库中记录时间戳
  4. 第四个就是直接将时间按需要的格式存储到字符串字段中
    在考虑有什么影响之前,我们首先需要知道这四种方式来存储时间他们有什么不同。

时间存储方式之间的异同

  1. datetime
    datetime格式数据的空间占用是8个字节;存储的时间范围是 0000-00-00 00:00:00.000000 - 9999-12-31 23:59:59.999999;另外在存储方式上,datetime存储时间时,写入的是什么,存储的就是什么,与时区没有关系。
  2. timestamp
    timestamp格式数据的空间占用是4个字节;存储的时间范围是 1970-01-01 00:00:01.000000 to 2038-01-19 03:14:07.999999;另外在存储方式上,timestamp存储时间时,本质存储的是时间戳。比如写入的是2022-04-22 22:09:30,且mysql时区为+8,所以存储的是UNIX_TIMESTAMP(2022-04-22 22:09:30)的值,与时区有关。为什么说与时区有关呢,因为从格式转换到时间戳时,是需要知道当前时间的时区的,当查询的时候,会从时间戳根据数据库的时区转换成对应时区的时间。
  3. 时间戳
    这本质上和timestamp存储是类似的,但是不同的一点是从时间转换成时间戳的这一步是应用服务去做的,所以mysql数据库就不需要关心时区的问题了,所以对于mysql来说,这也是与时区无关的。
  4. 字符串来存储
    我个人的感觉来说,其实和使用datetime是类似的,都是存入什么就是什么,所以也与时区无关。那与datetime不同的是,datetime格式作为mysql官方提供的两种时间存储类型之一,对于时间存储的支持上,肯定是比使用字符串来存储会更好的。

如何消除时间变化对于timestamp存储的时间的影响?

上面我们把四种时间存储方式都看了一下;发现当时区变化时,真正会有所影响的,只有一种类型,也就是timestamp。具体影响后的表现形式,其实上面的截图里面我们也看到了,那我们接下来一起看一下,如何去消除或者说避免时区对于我们timestamp时间的影响。

  1. 首先,从timestamp的定义来说,无论存储的是以utc还是时间戳来存储,在查询的时候最终呈现给我们看到的都是数据库时区对应的时间;所以我们看到的是什么时间,这与我们查询的时候数据库的时区是什么息息相关。这也是上面为什么会截图数据库时区的原因。
  2. 要是细心的同事可能会有出现一些疑惑。从上面的截图看,虽然两个数据库的系统时区不同,但是数据库时区来看 一个是 +08:00,一个是Asia/Shanghai;都是东八区,但是为什么时间显示不一致呢。这也是当时在处理这个问题的时候,将我们带入歧路的最大的原因,都认为+08:00==Asia/Shanghai。但是实际上,最后我们发现对于mysql的时区设置来说,+08:00真的不等于Asia/Shangha。当我们将迁移后的时区手动改成+08:00时,再去查询就能看到和迁移之前的数据库是一致的,而设置成Asia/Shanghai的时候,时间实际上是相差12个小时的,也就是数据库所在服务器的系统时区。上面我们也提到了,当mysql默认时区是system,也就是使用系统时区,所以其实就是说时区设置成Asia/Shanghai是无效的。
  3. 问题找到了,那怎么处理呢?第一种选择可以是修改数据库时区,设置成和我们之前的数据库时区一致就可以了。可以通过命令修改;也可以修改mysql配置文件,重启数据库后生效。
set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区 
set time_zone = '+8:00'; ##修改当前会话时区
  1. 但是,当因为某些原因,我们不能去改变数据库的全局时区的时候,我们可以怎么做呢。一个是当我们使用数据库工具链接数据库的时候,我们可以通过上面的set time_zone的方式修改当前会话时区,而在服务中,我们也可以在连接数据库的时候,在数据库连接参数中设置时区,和上面的设置会话时区的效果是相同的,就是设置本次数据库连接的数据库时区。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值