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

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

时间:2024-05-20 09:10:35浏览次数:25  
标签:00 01 zone time Mysql 时区 root 服务端 属性

一、说明

同事问我数据库的时区是客户端属性还是服务端属性,我觉得这个问题十分有意思,之前没怎么留意,自己来做下实验。
首先介绍几个术语。
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

([email protected])[(none)]> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2023-04-20 17:10:45 |
+---------------------+

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

([email protected])[hello]> create table t1(id int, dt datetime, tt timestamp);
([email protected])[hello]> insert into t1 values (1, '2022-01-01 12:00:00', '2022-01-01 12:00:00');
([email protected])[hello]> select * from t1;
+------+---------------------+---------------------+
| id   | dt                  | tt                  |
+------+---------------------+---------------------+
|    1 | 2022-01-01 12:00:00 | 2022-01-01 12:00:00 |
+------+---------------------+---------------------+

([email protected])[hello]> set time_zone='+12:00';
([email protected])[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客户端的结果:

([email protected])[(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客户端的结果:

([email protected])[(none)]> select sysdate();
+---------------------+
| sysdate()           |
+---------------------+
| 2023-04-20 19:04:35 |
+---------------------+

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

三、总结

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

标签:00,01,zone,time,Mysql,时区,root,服务端,属性
From: https://www.cnblogs.com/ddzj01/p/18201168

相关文章

  • Linux安装MySQL配置教程
    1.使用系统的root账户2.切换到 /use/local目录下3.下载mysql wgethttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.21-linux-glibc2.12-x86_64.tar.xz   也可以直接在官方下载最新版本 官方下载 选择linux4.解压mysql tarxvJfmysql-8.0.21-li......
  • MySQL查询优化
    MySQL查询优化参考:Mysql数据库查询好慢,除了索引,还能因为什么?一、MySQL查询效率低的常见原因硬件性能不足磁盘IO速度慢CPU性能不足内存不足查询语句不合理使用过于复杂的子查询或者连接(JOIN)使用SELECT*而非选择特定的列使用非索引列进行条件判断表结构问题......
  • 连表操作、子查询、pymysql 模块、sql注入问题(感觉已没有)
    【连表操作】1建表2createtabledep1(3idint,4namevarchar(20)5);6createtableemp1(7idintprimarykeyauto_increment,8namevarchar(20),9sexenum('male','female')notnulldefault'male&......
  • 快速理解MySQL null的10大坑
    创建表时应当设置notnull,添加一个默认值0或''去替代null。sum('field')的坑若一列的所有值都是null,那么sum函数的结果不是0,而是null,所以可能会因为值的类型兼容问题,出现意料之外的情况。null值会有NPE问题。count('field')的坑有null的列,count不会+1。where('field')的坑n......
  • mysql 统一修改字符集和字段属性
    --修改表字符集SELECTCONCAT("ALTERTABLE`",TABLE_NAME,"`CONVERTTOCHARACTERSETutf8mb4COLLATEutf8mb4_general_ci;")AStarget_tablesFROMINFORMATION_SCHEMA.TABLESWHERETABLE_SCHEMA="uat-zpg"ANDTABLE_TYPE="BASETABLE&q......
  • MySQL的索引优化
    一、索引的使用场景1、全值匹配通过主键索引查询mysql>explainselect*fromt_goodswhereid=1\G;***************************1.row***************************id:1select_type:SIMPLEtable:t_goodspartitions:NULLtyp......
  • java+mybatis+easyExcel快速导入excel数据到MySQL
    这里有一些数据需要导入数据库。demo地址:importExcel使用步骤如下:一、修改database相关内容 1.修改application.properties文件中数据库地址及信息二、新建实体类1.新建excel数据所符合的实体类,这里举例Excel中有如下数据,表头字段为“username”。数据......
  • Mysql新建日历表
    新建最近几十年的天 CREATETABLEifnotexistscalendar(account_daydate);INSERTINTOcalendar(account_day)SELECTDATE_ADD('2024-01-01',INTERVALnDAY)FROM(SELECTa.N+b.N*10+c.N*100+d.N*1000ASnFROM(SELECT0ASNUNIONSELECT1......
  • MySQL精度问题-hekui
    一、MySQL中datetime类型怎么处理毫秒MySQL中datetime日期类型,默认是精确到秒的。从MySQL5.6.4版本开始,可以设置精度,如datetime(3)表示精确到毫秒类型说明插入时赋值DB实际存储datetime(0)或datetime精确到秒2024-05-1900:00:00:4992024-05-1900:00:00:500202......
  • mysql5.7 报错:[ERROR] InnoDB: Ignoring the redo log due to missing MLOG_CHECKPOIN
    mysql5.7启动报错:2024-05-19T02:02:14.453082Z0[Warning]TIMESTAMPwithimplicitDEFAULTvalueisdeprecated.Pleaseuse--explicit_defaults_for_timestampserveroption(seedocumentationformoredetails).2024-05-19T02:02:14.453139Z0[Note]--secure-file......