2

我正在玩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' )));

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

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

如果添加毫秒

PARTITION p_s18 VALUES LESS THAN (UNIX_TIMESTAMP('2012-09-18 00:00:00.000')

==> 错误 1697 (HY000): 分区 'p_s18' 的 VALUES 值必须具有 INT 类型

OK 和以前一样的故事

如果我更改我的 tstamp 列的定义并且不使用毫秒

`TSTAMP` timestamp

==> 它工作得很好,但我不会存储我的毫秒数,这不是我想要的。

任何的想法?

4

3 回答 3

3

MySQL 在使用时间戳对表进行分区时仍然存在一些问题,比如这个,这可能会导致 InnoDB 崩溃。他们在过去以小数秒为单位对时间戳的行为进行了一些更改。

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

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

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

于 2012-09-25T13:46:34.183 回答
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 语句会导致导入失败并显示语法错误。”

于 2012-09-26T09:15:08.960 回答
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)
);
于 2019-10-11T11:08:42.370 回答