Mysql - 数据库时区是客户端属性还是服务端属性

news/2024/11/16 17:56:11/文章来源:https://www.cnblogs.com/ddzj01/p/18201168

一、说明

同事问我数据库的时区是客户端属性还是服务端属性,我觉得这个问题十分有意思,之前没怎么留意,自己来做下实验。
首先介绍几个术语。
GMT(Greenwich Mean Time),格林尼治平均时间。
UTC(Coordinated Universal Time),协调世界时。
CST(China Standard Time),中国标准时间,也称北京时间。
根据维基百科,格林尼治标准时间的正午是指当平太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治平时基于天文观测本身的缺陷,目前已经被原子钟报时的协调世界时(UTC)所取代。协调世界时是世界上调节时钟和时间的主要时间标准,计算机中的网络时间协议(NTP, Network Time Protocol)就是用的协调世界时。不过,GMT和UTC相差不超过1秒,对绝大多数系统来说,可以认为这两个时间等价。中国的标准时间就是在UTC上面加8小时。

二、测试

测试使用Mysql8,CentOS7,Jdbc

我现在的时间是北京时间 2023-4-22 19:42,我将服务器的时间设置成任意一个时间,时区设置成东京,即(UTC+9)。

[root@xbz ~]# timedatectl list-timezones  // 列出所有时区
[root@xbz ~]# timedatectl set-timezone Asia/Tokyo  // 设置成东京时区
[root@xbz ~]# date -s '2023-4-20 15:00:00'  // 设置任意时间
[root@xbz ~]# date -R  // 查看系统时间
Thu, 20 Apr 2023 15:00:41 +0900 

将Mysql数据库重启,Mysql关于时区有两个参数
system_time_zone 系统时区,在Mysql启动时会检查当前系统的时区并根据系统时区设置。参数不可修改。
time_zone 会话时区,默认为system,即使用全局参数system_time_zone的值。可以动态修改。

(root@localhost)[(none)]> show variables like '%zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | SYSTEM |
+------------------+--------+

会话时区的修改可以使用命令set global time_zone='+8:00'修改,或者在参数文件中设置default_time_zone='+8:00'。为了实验,我将客户端的时区设置为'+11:00'。

(root@localhost)[(none)]> set global time_zone='+11:00';
(root@localhost)[(none)]> show variables like '%zone%';  // 再开一个窗口查询
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | +11:00 |
+------------------+--------+

数据库服务器在UTC+9,数据库客户端时区设置的是UTC+11。分别查服务器的时间和数据库的时间,数据库的时间相比服务器的时间要快了2小时,这就是参数time_zone在起作用。

[root@xbz ~]# date -R
Thu, 20 Apr 2023 15:10:58 +0900(root@192.168.1.82)[(none)]> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2023-04-20 17:10:45 |
+---------------------+

再来看一个例子,我在数据库中分别创建一个datetime和timestamp两个字段,插入同一个时间。然后将客户端的时区换一下,会发现timestamp的时间也跟着发生变化了,这其实是由于MySQL将timestamp列的值从当前时区转换为UTC时间进行存储,查询时,将数据从UTC转换为检索的当前时区。

(root@192.168.1.82)[hello]> create table t1(id int, dt datetime, tt timestamp);
(root@192.168.1.82)[hello]> insert into t1 values (1, '2022-01-01 12:00:00', '2022-01-01 12:00:00');
(root@192.168.1.82)[hello]> select * from t1;
+------+---------------------+---------------------+
| id   | dt                  | tt                  |
+------+---------------------+---------------------+
|    1 | 2022-01-01 12:00:00 | 2022-01-01 12:00:00 |
+------+---------------------+---------------------+(root@192.168.1.82)[hello]> set time_zone='+12:00';
(root@192.168.1.82)[hello]> select * from t1;
+------+---------------------+---------------------+
| id   | dt                  | tt                  |
+------+---------------------+---------------------+
|    1 | 2022-01-01 12:00:00 | 2022-01-01 13:00:00 |
+------+---------------------+---------------------+

接下来测试下Jdbc中的表现

public class JdbcTimeZoneTest {public static void main(String[] args) throws Exception {String user = "scott";String password = "tiger";String driver = "com.mysql.cj.jdbc.Driver";String url = "jdbc:mysql://192.168.1.82/hello";  Class.forName(driver);Connection connection = DriverManager.getConnection(url, user, password);String sql = "select sysdate()";Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);while (resultSet.next()) {System.out.println(resultSet.getTimestamp(1));}}
}

运行结果:
2023-04-20 19:02:44.0

mysql客户端的结果:

(root@192.168.1.82)[(none)]> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2023-04-20 19:02:47 |
+---------------------+

可以看到jdbc跟mysql客户端显示的时间一致。

url加入这个参数?serverTimezone=Asia/Shanghai
运行结果:
2023-04-20 19:03:19.0
可以看到时间好像没什么变化

当我把jdbc所运行的机器时间调整成(UTC+3)
微信截图_20230418170911.png

再运行一次,结果:
2023-04-20 14:04:17.0

mysql客户端的结果:

(root@192.168.1.82)[(none)]> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2023-04-20 19:04:35 |
+---------------------+

jdbc所显示的时间为什么会比mysql客户端显示的时间慢5个小时呢,这是由于serverTimezone=Asia/Shanghai是在东八区,而我的本机设置的时区是东三区,差了5个小时,所以相较于Mysql客户端就有5个小时的差距。所以serverTimezone要么不设置,要么设置成jdbc所运行的机器的时区。

三、总结

  1. 设置好服务器的时区和mysql的时区,避免一些不必要的坑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/709050.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sql求连续值问题

一. 找出表test1中tflag字段连续出现3次及以上为1的行思路:1. 对行进行编号,2. 对相邻三行进行求和算出值作为sumflag,3. 如果值为3,则该行以及接下来的2行都输出出来,通过自关联解决。 WITH tmp AS (SELECT tday, tflag, row_number() over(partition by null order by t…

Xming - xmanager的替代方案

一、概述 安装某些数据库的时候使用图像化还是比较方便的,但是由于服务器一般不提供图形化界面。之前一直都是使用Xmanager去导出图形,但是Xmanager是收费的,公司不让用,所以找了一款可以完美替代的产品Xming,本文将介绍xming如何安装和使用。 二、安装 1. 下载 https://s…

使用 Spacesniffer 找回 48G 系统存储空间的总结

Spacesniffer 是一个免费的文件扫描工具,操作完毕,我成功找回了 48G 的C盘空间前言Spacesniffer 是一个免费的文件扫描工具,通过使用树状图可视化布局,可以立即了解大文件夹的位置,帮助用户处理找到这些文件夹当前系统C盘空间清理后系统C盘空间下载 Spacesniffer 下载地址…

在WebGL中使用GLSL实现光线追踪

Update:git地址 https://github.com/mahiru23/raytrace 本文的根本目标是在WebGL中使用GLSL实现光线追踪,无图(懒得放了),仅供参考。 在一切开始之前,我们默认对GLSL的基本语法有所了解,不理解请自行查找。 一些需要重点关注的东西,请确认自己完全明白这一点再继续: …

苹果电脑进入 Macos 恢复启动

进入Macos 恢复启动 intel 芯片   从“macOS 恢复”启动按下并松开电源按钮以将 Mac 开机,然后立即按住键盘上 Command (⌘) 和 R 这两个按键。持续按住这两个按键,直到看到 Apple 标志或旋转的地球。系统可能会提示你选择 Wi-Fi 网络或连接网线。要选择 Wi-Fi 网络,请使用…

Hello Laravel! Laravel 入门教程

Hello Laravel! 准备 目录Hello Laravel! 准备什么是 Laravel?为什么选择 Laravel?优雅的语法丰富的功能强大的社区支持安全性易于扩展Laravel 的流行程度其他流行的 Web 框架对比环境准备下载 Laragon设置工作目录添加 PHP 版本设置环境变量Composer 安装初始化 Laravel 项目…

Hello Laravel! 准备

Hello Laravel! 准备 目录Hello Laravel! 准备什么是 Laravel?为什么选择 Laravel?优雅的语法丰富的功能强大的社区支持安全性易于扩展Laravel 的流行程度其他流行的 Web 框架对比环境准备下载 Laragon设置工作目录添加 PHP 版本设置环境变量Composer 安装初始化 Laravel 项目…

WSL2 Xlaunch 转发显示图像

export DISPLAY=localhost:0.0 export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk {print $2}):0 控制面板/系统和安全/Windows Defender防火墙/允许应用通过Windows防火墙 更改设置->勾选 VcXsrv windows xserver待完成

5款.NET开源、免费、功能强大的图表库

LiveCharts2 LiveCharts2是一个.NET开源(MIT License)、简单、灵活、交互式且功能强大的.NET图表、地图和仪表,现在几乎可以在任何地方运行如:Maui、Uno Platform、Blazor-wasm、WPF、WinForms、Xamarin、Avalonia、WinUI、UWP。GitHub开源地址:https://github.com/beto-r…

从误解到理解:非暴力沟通的艺术

非暴力沟通的艺术在生活的喧嚣与忙碌中,我们时常迷失于自我,忘记了与人沟通时的基本准则——尊重与理解。当再次拾起《非暴力沟通》这本书,我意识到,过去的沟通方式不仅让我与身边人的关系变得紧张,也让我自己背负了不必要的心理负担。 许多人对我的初印象是友善、和蔼的,…

5/20死神永生服周报第二期

目录死神永生新闻 关于储存开放世界需要多大空间 论Factions的玩法死神永生新闻前一周的治理新闻时间 人 行为 处罚方案5.16 Atom446649443 随意保护 Ban5.19 Galactic654221024 炸服 清空背包+设为生存关于储存开放世界需要多大空间\(\color {gray} \small \texttt {By Loki71…

efcore如何优雅的实现按年分库按月分表

efcore如何优雅的实现按年分库按月分表 介绍 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案,具有零依赖、零学习成本、零业务代码入侵适配 距离上次发文.net相关的已经有很久了,期间一直在从事java相关的工作,一不…