代码之家  ›  专栏  ›  技术社区  ›  Vincent Duprez

在非UTC服务器上,所有带有时间戳的MySQL导出文件中是否都存在错误?

  •  0
  • Vincent Duprez  · 技术社区  · 6 年前

    只需将一个SQL数据库从一台服务器移到另一台服务器上

    我理解MySQL中的时间戳字段存储为4字节整数(不区分时区),并在当前服务器(MySQL服务器)时区设置中呈现给用户。 我说的对吗?

    现在,当欧洲的时间从夏季变为10月的结束时间(UTC+2到UTC+1)时,有一个小时的时间重叠。

    这是有意义的,不是问题,因为我们“知道”服务器知道区别,因为它将thim存储在unix-utc时间戳中。

    我还是对的吗?

    现在,当我将数据库导出从一个数据库移动到另一个数据库时,时间戳字段不会以整数的形式移动,而是作为人类可读的时间字符串移动:

    只是一个例子:

    (1,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 17:38:16',0,NULL,NULL,NULL,NULL,0,NULL),
    (2,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 20:00:00',1,NULL,NULL,NULL,NULL,0,NULL),
    (3,'AAAA01',6.00,NULL,NULL,NULL,'2017-07-28 21:39:07',0,NULL,NULL,NULL,NULL,0,NULL),
    (4,'AAAA01',5.50,NULL,NULL,NULL,'2017-07-28 21:42:15',0,NULL,NULL,NULL,NULL,0,NULL),
    (5,'AAAA01',5.00,NULL,NULL,NULL,'2017-07-29 12:55:48',0,NULL,NULL,NULL,NULL,0,NULL),
    

    您可以看到此字段:

    `received` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    

    但作为人类可读的字段存储。

    接收服务器如何知道此字段是在时间更改之前还是之后(10月)

    时间变化一年发生两次,在春天它向前走一个小时,所以没有混乱,因为只有一个小时的差距,但在秋天它向后走,并“覆盖”同一个小时。

    时区转换

    MySQL服务器如何能够回答这一次,因为它代表了两个不同的时间:

    选择Convert_TZ(“2018-10-28 02:40”、“欧洲/巴黎”、“UTC”)。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Michael - sqlbot    6 年前

    mysql服务器的时区是 违约 用于这些转换的时区。它可以在每个连接的基础上被覆盖。这就是为什么,在这里,使这个工作。

    什么时候? mysqldump 查询服务器以检索要写入备份文件的数据,首先发送:

    SET TIME_ZONE='+00:00';
    

    这会将mysqldump连接的会话(连接)时区设置为utc,这会导致 TIMESTAMP 将由服务器以UTC格式发送并以这种方式写入备份文件的列。

    在转储文件的顶部附近,它还添加了以下内容:

    /*!40103 SET TIME_ZONE='+00:00' */;
    

    这个 /*! ... */ is not really a comment 即使看起来像。这个 !40103 向任何MySQLServer4.01.03版或更高版本发送信号,使其正常执行嵌入语句,从而在将要还原转储的连接上设置会话时区为UTC,以便将这些时间戳作为字符串正确存储。

    DATETIME 列不进行这些转换--仅 时间戳 …但为了 时间戳 列中,新服务器上不应存在不正确的值。转储文件中的值是UTC——它也是本机内部存储格式的时区(在技术上完全不可知)。


    还请注意,将服务器时区设置为除UTC以外的任何其他值已不再被视为最佳实践。本地时间是一个表示问题,最好由应用程序来处理,而不是由数据库来处理。UTC没有像当地时区那样的模棱两可——比如春天的错失时间和秋天的重复时间,这在许多当地时区都可以找到。

    推荐文章