为什么MySQL 使用timestamp可以无视时区问题.

为什么MySQL使用timestamp可以无视时区问题?

在MySQL中,使用timestamp类型进行日期和时间的存储,它是一种与时区无关的数据类型。无论你是哪个时区,时间都会以相同的方式存储在timestamp类型字段中。下面分为以下几个方面进行讲解。

  1. timestamp存储的时间是UTC(协调世界时)

如下面的代码块所示,我们可以使用NOW()函数获取当前时间并插入到一个timestamp类型的字段中。

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `user` (`name`) VALUES ('John');

查询该记录的created_at字段,返回的时间与查询服务器的时区无关,在MySQL内部都是UTC时间。

SELECT `id`, `name`, `created_at`
FROM user
WHERE name = 'John';

返回结果如下:

+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | John | 2021-08-31 12:34:56 |
+----+------+---------------------+
  1. MySQL会自动将本地时间转换为UTC时间进行存储

在MySQL中,无论你在哪个时区将本地时间存储到timestamp类型的字段中,MySQL都会将本地时间转换为UTC时间,然后存储到该字段中。也就是说,时间的存储方式与时区无关,只与UTC有关。下面的代码演示了这一点。

例如在中国的时区设置为CST(中国标准时间),如果你在上海服务器设置一个时间并存储到timestamp类型的字段中,如下所示。

SET time_zone = '+8:00';
SELECT NOW();

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `user` (`name`, `created_at`) VALUES ('John', '2021-08-31 12:34:56');

程序在上海服务器的时区下运行,现在我们要查询北京的时间,将时区设置为东八区,如下所示。

SET time_zone = '+8:00';
SELECT `id`, `name`, `created_at`
FROM user
WHERE name = 'John';

结果如下,可以看到存储到timestamp类型的字段中的时间会被自动转换为UTC时间。

+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | John | 2021-08-31 04:34:56 |
+----+------+---------------------+
  1. MySQL会将timestamp类型的字段转换为本地时间进行显示

当我们在查询timestamp类型字段时,MySQL会自动将该字段的UTC时间转为当前的时区,然后显示在客户端上。这样我们在使用timestamp类型存储时间时,不需要考虑到时区的问题。下面的代码演示了这一点。

例如在中国的时区设置为CST(中国标准时间),我们将一个timestamp类型的字段中存储了UTC时间。查询该记录时,MySQL会将存储的UTC时间自动转为本地时间进行显示,如果你在上海查询,如下所示。

SET time_zone = '+8:00';
SELECT `id`, `name`, `created_at`
FROM user
WHERE name = 'John';

结果如下,可以看到该条记录的时间已经自动转换为中国标准时间(CST),时间显示时区与查询时设置的时区相同。

+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | John | 2021-08-31 12:34:56 |
+----+------+---------------------+
  1. 示例1

我们在数据库中插入一个时间,并将本地的时区设置为东八区,然后查询该时间,并将时区设置为美国洛杉矶的时区。代码如下:

SET time_zone = '+8:00';
SELECT NOW();

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `user` (`name`, `created_at`) VALUES ('Lucy', '2021-09-01 12:34:56');

查询语句:

SET time_zone = '-7:00';
SELECT `id`, `name`, `created_at`
FROM user
WHERE name = 'Lucy';

结果如下,我们查询时的时区是美国洛杉矶的时区,但是查询结果中的时间已经自动转换为美国洛杉矶的本地时间。

+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | Lucy | 2021-09-01 05:34:56 |
+----+------+---------------------+
  1. 示例2

我们在数据库中插入一个时间,并将本地的时区设置为美国洛杉矶的时区,然后查询该时间,并将时区设置为中国上海的时区。代码如下:

SET time_zone = '-7:00';
SELECT NOW();

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `user` (`name`, `created_at`) VALUES ('Lucy', '2021-09-01 12:34:56');

查询语句:

SET time_zone = '+8:00';
SELECT `id`, `name`, `created_at`
FROM user
WHERE name = 'Lucy';

结果如下,我们查询时的时区是中国上海的时区,但是查询结果中的时间已经自动转换为中国上海的本地时间。

+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | Lucy | 2021-09-01 03:34:56 |
+----+------+---------------------+

综上所述,MySQL使用timestamp可以无视时区问题,主要是因为它存储的是UTC时间,并且自动将本地时间转换为UTC时间进行存储,同时在查询时会将UTC时间转换为本地时间进行显示,这种机制可以让我们在使用timestamp存储时间时,无需考虑时区的问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:为什么MySQL 使用timestamp可以无视时区问题. - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • mysql语句实现简单的增、删、改、查操作示例

    MySQL是一种常用的数据库管理系统,本篇攻略将向您介绍MySQL语句如何实现简单的增、删、改、查操作。下面通过两个示例来详细说明。 示例一:添加数据 向一个名为users的表中添加一条数据,包含id、name、age、sex四个字段,分别为1、Lucy、22、女。该操作的MySQL语句如下: INSERT INTO users (id, name, age…

    database 2023年5月21日
    00
  • centos6.8下redis的安装和配置

    下载、安装 在redis官网可以获取到最新版本的redis 进入/usr/local/目录,执行如下命令 wget http://download.redis.io/releases/redis-4.0.2.tar.gztar xzf redis-4.0.2.tar.gzcd redis-4.0.2make 执行make构建redis时报如下错误,这是因为没…

    Redis 2023年4月13日
    00
  • Mybatis中Mapper标签总结大全

    下面我将详细讲解”Mybatis中Mapper标签总结大全”的完整攻略。 一、什么是Mapper标签 Mapper标签是Mybatis中最为重要、最为核心的标签,用于编写SQL映射语句、处理结果映射等操作,是实现Mybatis操作数据库的关键。 二、Mapper标签的使用方式 1.使用Mapper标签的四个步骤 使用Mapper标签一般是通过以下四个步骤来完…

    database 2023年5月21日
    00
  • mysql优化利器之explain使用介绍

    MySQL 优化利器之 Explain 使用介绍 什么是 Explain ? Explain 是 MySQL 内置的一个用于分析查询语句的工具,在分析查询语句时,我们可通过 Explain 得到一份详细的优化建议。 Explain 使用方法 Explain 的语法如下: EXPLAIN [EXTENDED] SELECT * FROM 表名 WHERE 条件…

    database 2023年5月19日
    00
  • redis实现加锁的几种方法示例详解

    1. redis加锁分类 redis能用的的加锁命令分表是INCR、SETNX、SET 2. 第一种锁命令INCR 这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一。然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中。     1、 客户端A请求服务器获…

    Redis 2023年4月13日
    00
  • 利用mycat实现mysql数据库读写分离的示例

    下面是详细讲解利用mycat实现mysql数据库读写分离的示例的完整攻略: 简介 Mycat是一个高性能和可扩展的分布式数据库系统,主要用于数据库读写分离、数据分片等场景。本文将介绍如何使用Mycat实现MySQL数据库的读写分离。 步骤 下载Mycat软件包 在Mycat的官网(http://www.mycat.io/)上下载最新版本的Mycat软件包,并…

    database 2023年5月22日
    00
  • CentOS 7 x64下Apache+MySQL(Mariadb)+PHP56的安装教程详解

    CentOS 7 x64下Apache+MySQL(Mariadb)+PHP56的安装教程详解 1. 安装Apache 1.1 安装Apache Httpd软件包 sudo yum install httpd 1.2 开启防火墙端口 sudo firewall-cmd –permanent –add-port=80/tcp sudo firewall-c…

    database 2023年5月22日
    00
  • 在ASP.NET中用存储过程执行SQL语句

    在ASP.NET中,使用存储过程执行SQL语句可以提高应用程序的性能和安全性。下面是一些执行该过程的步骤: 步骤 1:创建存储过程 首先,需要创建一个存储过程。可以使用 Microsoft SQL Server 等数据库管理系统创建该存储过程。以下示例创建一个简单的存储过程,用于获取用户的姓名: CREATE PROCEDURE GetUserName @u…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部