Mysql 5.6对时间戳进行分区(以微秒为单位)

时间:2012-09-25 13:15:18

标签: mysql database-partitioning

我正在玩mysql 5.6。 我特别感兴趣的可能性: DATETIME或TIMESTAMP值可以包括最小微秒(6位)精度的尾随小数秒部分。

我想要的是使用这样的时间戳对表进行分区。

示例:

CREATE TABLE `VALUE_BIS` (
  `TSTAMP` timestamp(3) NOT NULL,
  `ATTRIBUTE_ID` int(11) NOT NULL,
  `VAL` int(11) unsigned NOT NULL,
  PRIMARY KEY (`ATTRIBUTE_ID`,`TSTAMP`)
)  PARTITION BY RANGE (UNIX_TIMESTAMP(TSTAMP))
     (PARTITION p_s18 VALUES LESS THAN (UNIX_TIMESTAMP('2012-09-18 00:00:00')),
     PARTITION p_s19 VALUES LESS THAN (UNIX_TIMESTAMP('2012-09-19 00:00:00')),
     PARTITION p_Max VALUES LESS THAN (UNIX_TIMESTAMP('2020-09-26 00:00:00' )));

==>错误1491(HY000):PARTITION函数返回错误的类型

*我认为它正常,因为它返回unixtimestamp_seconds.microseconds,这不是一个整数*

如果添加像

那样的毫秒
PARTITION p_s18 VALUES LESS THAN (UNIX_TIMESTAMP('2012-09-18 00:00:00.000')

==> ERROR 1697(HY000):分区'p_s18'的VALUES值必须为INT

和以前一样的故事

如果我改变了tstamp列的定义而不使用miliseconds

`TSTAMP` timestamp

==>它工作正常,但我不会存储我的毫秒,而不是我想要的。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

MySQL在使用时间戳like this one, which can cause a InnoDB crash对表进行分区时仍然存在问题。他们过去对timestamp with fractional seconds的行为做了一些改变。

我的第一个猜测是,存储和使用分形秒的方式与unix_timestamp发生冲突。因此无法正确创建分区(因为类型错误)...因此会生成您遇到的错误消息。

解决方法是添加第二个字段,该字段仅包含没有分形秒的时间戳,并将其用作范围标识符。

无论哪种方式,您都应该报告错误。

答案 1 :(得分:0)

根据Bjoern的建议,我向mysql跟踪器提交了一个错误(http://bugs.mysql.com/bug.php?id=66958)。 这是他们的答案(对他们来说这不是一个错误)

记录不支持时间戳(N): http://dev.mysql.com/doc/refman/5.5/en/upgrading-from-previous-series.html

“不兼容的更改:在非常旧版本的MySQL(4.1之前)中,TIMESTAMP数据类型支持显示宽度,从MySQL 4.1开始默认忽略。这在MySQL 5.1中已弃用,在MySQL 5.5中完全删除当尝试将TIMESTAMP(N)列与MySQL 5.5或更高版本的服务器一起使用时,这些行为更改可能导致两种问题:

将MySQL 5.0或更早版本服务器中创建的转储文件(例如,使用mysqldump创建的转储文件)从较新的发行版系列导入服务器时,包含TIMESTAMP(N)的CREATE TABLE或ALTER TABLE语句会导致导入到因语法错误而失败。“

答案 2 :(得分:0)

对于MySQL 8和MariaDB 10仍然存在此问题。

以上内容是关于MySQL无法分区的正确信息。 但是您不必更改表,您可能不需要使分区变得精细。 可以将时间戳记设为底数,这是一种快速操作,并且可以与任何时间戳记(N)一起使用

示例:

CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( FLOOR(UNIX_TIMESTAMP(report_updated)) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN (MAXVALUE)
);