如何从MySQL中的UNIX_TIMESTAMP()获取UTC日期时间

时间:2016-11-30 22:54:03

标签: mysql partitioning

我想知道如何从mysql中的unix_timestamp获取utc datetime。

但是,我不应该使用CONVERT_TZ。

(因为在分区时无法使用时区功能。)

SQL架构中发生错误......

CREATE TABLE `table` (
  `idx` BIGINT(20) NOT NULL,
  etc...
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE( YEAR(CONVERT_TZ(from_unixtime(`idx` >> 24), @@session.time_zone, '+00:00')) )
SUBPARTITION BY HASH ( MONTH(CONVERT_TZ(from_unixtime(`idx` >> 24), @@session.time_zone, '+00:00')) )
SUBPARTITIONS 12 (
    PARTITION p2016 VALUES LESS THAN (2016),
    PARTITION p2017 VALUES LESS THAN (2017),
    PARTITION p2018 VALUES LESS THAN (2018),
    PARTITION p2019 VALUES LESS THAN (2019),
    PARTITION p2020 VALUES LESS THAN (2020)
)

2 个答案:

答案 0 :(得分:0)

我认为您的问题不是CONVERT_TZ,而是FROM_UNIXTIME

FROM_UNIXTIME将Integer作为参数 - 这意味着32位。

如果您采用今天的unix-timestamp:1480546792,向右移位24位 - 您只是超过unix_time上有效参数的32位限制。

from_unixtime只能处理最多2147483647的参数 - 这意味着它可以工作到2038-01-19 04:14:07

我也遇到过这个问题,自2002年以来,对此的解决方案是“正在开发中”。

在最终解决之前,您应该使用date_add使用变通方法。而不是

from_unixtime (x)

使用

date_add(from_unixtime(0), INTERVAL x second)

结果(一个或多个):

SELECT from_unixtime (2147483647); //2038-01-19 04:14:07 
SELECT from_unixtime (2147483648); //NULL

SELECT date_add(from_unixtime(0), Interval 2147483647 second) //2038-01-19 04:14:07
SELECT date_add(from_unixtime(0), Interval 2147483648 second) //2038-01-19 04:14:08

答案 1 :(得分:0)

你在这里受到约束。 每当TIMESTAMP数据项呈现为日期/时间项时,MySQL会将其隐式地从UTC转换为本地时间(其中本地时间由当前连接的time_zone设置控制。

这使得使用YEAR(timestamp)来控制分区变得不可行。使用MySQL date and time functions提取年份的任何事情都会执行转换。这意味着任何此类转换都是不确定的。这意味着你不能用它来控制分区。

您可以使用UNIX_TIMESTAMP() DIV ( 365 * 24 * 60 *60)或几年的近似值来控制分区。它将是紧密的,不精确的和确定性的。

或者您可以使用UNIX_TIMESTAMP() DIV 16777216UNIX_TIMESTAMP() >> 24进行分区。那是2 ^ 24.这是一个超过194天。这是武断的。但如果多年是好的分区休息时间,那么这些时间段也是如此。并且,您已经在索引中使用了位域模型。