【MySQL】解决mysql出现的时区问题

前言

目录

1.mysql时区及时间戳概念
2.BRIGHTHOUSE引擎的表概念
3.bug案例分析

Mysql时区及时间戳概念

要记住,时间与时区有关,但是时间戳与时区是没有关系的,时间戳都是一致性的,只不过因为时区的不一致导致展示的时间是不一样

UTC/时间戳的概念

utc的概念的话直接看这个文章:https://blog.csdn.net/weixin_39759989/article/details/111811252?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-4&spm=1001.2101.3001.4242
也没什么必要重新再写了

mysql时区的概念

在本地使用的话,系统默认使用的是utc+8的时区,就是北京时间
在mysql中,若用timestamp类型来存储的话,默认是存储utc时区的时间戳,但是在展示的时候,会默认使用当前系统的时区来展示时间,如存储的时间戳为1356969600,这个时候会默认以utc+8的时区来展示,就是2013-01-01
查看mysql时区的sql语句如下

mysql> show variables like "%time_zone";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CEST   |
| time_zone        | SYSTEM |
+------------------+--------+

BRIGHTHOUSE引擎的表概念

    对于mysql表引擎的概念,大家就看看这篇博文,写得挺好的:https://www.cnblogs.com/sunsky303/p/8274586.html。
我就懒得复制黏贴了,还是自己写原创好一点。
这里的话主要说一下
  BRIGHTHOUSE引擎的概念:
    brighthouse是infobright数据库的关键引擎。infobright 数据库是基于mysql的,它的设计主要是用于大规模的数据仓库和分析优化。(等下业务场景就要说下infobright了)
    基本上用的就是infobright的社区版,对于社区版的话,社区版的不支持 insert,update,delete对数据操作和alter对结构操作,数据存储高压缩一般为18:1,不能与MyISAM,InnoDB等引擎进行连接查询 , 数据必须使用 LOAD 方式写入。
但是有一个优点,就是比inndb快几十倍!

bug案例分析

当前有一个业务场景,客户有一张在mysql的基础表,有个功能叫抽取到高速表(高速表自身配置),这里配置了infobright为高速表,然后将mysql的基础表数据抽取出来,插入到高速表中,之后的查询都从高速表中获取,从而达到快速的查询数据
mysql中有一列为(使用datetime存储)

+------------------+--------+
| date             | Value  |
+------------------+--------+
| orderdate        | 2013-01-01 00:00:00|
+------------------+--------+

抽取到infobright中为(使用timestamp存储)

+------------------+--------+
| date             | Value  |
+------------------+--------+
| orderdate        | 2013-01-01 00:00:00|
+------------------+--------+

可以看到显示还是为 2013-01-01 00:00:00 (主要是因为显示时会默认以当前时区展示时间)

转化为时间戳时看以下图例分享

在这里插入图片描述
然后发现一个问题:

1、在普通的mysql引擎如InnoDB下的话,无论是否嵌套或嵌套多少层,时间戳都为:1356969600(2013-01-01)

2、若使用BRIGHTHOUSE引擎的话,只有一个查询的时候,时间戳为1356969600(2013-01-01),若orderdate在内嵌查询中,外层查询查询到的时间戳就会为1356940800(2012-12-31 16:0:0)

根据以上问题猜测,有可能在查询时间戳的时候,在BRIGHTHOUSE引擎中,一个查询查询时间戳会使用mysql设置的时区(当前为系统时区),若使用了外层查询的时候,直接使用了utc时区

在这里插入图片描述
所以感觉这也可以解析一个问题,为什么直接查询时候,dateTime转换时间戳是2013年(utc +8),而在外层查询的时候dateTime转换的时间戳是2012年(utc)。因为在外层默认使用了utc,导致了时间戳少8个小时,转换时间也出现了问题。

这个回答的话:https://stackoverflow.com/questions/409286/should-i-use-the-datetime-or-timestamp-data-type-in-mysql。有回答到时间戳是以utc来存储,通过函数获取的话会根据当前时区获取时间戳。但是至于为什么BRIGHTHOUSE引擎外层查询使用函数的的时候会默认使用utc,这个就没搞懂mysql原理了

解决方案

其实对于解决方案的话,没什么太好的解决方案(除非往深层跟到mysql的原理)
然后就使用了如下方案解决
使用CONVERT_TZ函数去获取时间,先将时间转化为当前时区,使获取的时间是当前时区的时间。就如上面的sql

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值