我想知道如何从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)
)
答案 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 16777216
或UNIX_TIMESTAMP() >> 24
进行分区。那是2 ^ 24.这是一个超过194天。这是武断的。但如果多年是好的分区休息时间,那么这些时间段也是如此。并且,您已经在索引中使用了位域模型。