如何对MySql表进行分区以便与90天旋转分区一起使用?

时间:2013-06-27 20:13:44

标签: mysql partitioning

我想创建一个分区表,它将填充数亿条记录。如何使用分区如何将特定日期的记录放入一个分区,然后将第二天放入另一个分区等等。然后在九十多天后我可以从最旧的分区中删除旧数据。

我尝试了这个声明(哈希函数使用模数来计算分区数量来计算哪个分区获取数据)。这确保了每天使用92个分区中的不同分区;除了它不起作用。

CREATE TABLE records(
    id INT NOT NULL AUTO_INCREMENT,
    dt DATETIME,
    PRIMARY KEY (id)
)
PARTITION BY HASH((MOD(DAYOFYEAR(dt), 92) + 92))
PARTITIONS 92;

上述代码段的问题是哈希表达式中使用的列必须是表中的唯一键。

如何解决这个问题,以便根据每天的记录有90个(ish)旋转分区?

如果我只是将dt列添加到主键,如果选择日期范围,则似乎会触及所有分区,这不是我想要的。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

原因是要在日期字段上进行分区并按范围查询,您必须在分区表达式中使用YEAR()TO_DAYS()

像这样的分区按预期工作:

CREATE TABLE `alert` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `eventId` int(10) unsigned NOT NULL,
  `occurred` datetime NOT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
/*!50100 PARTITION BY RANGE (TO_DAYS(occurred))
(PARTITION 28_06 VALUES LESS THAN (735413) ENGINE = InnoDB,
 PARTITION 29_06 VALUES LESS THAN (735414) ENGINE = InnoDB,
 PARTITION 30_06 VALUES LESS THAN (735415) ENGINE = InnoDB,
 PARTITION 01_07 VALUES LESS THAN (735416) ENGINE = InnoDB,
 PARTITION 02_07 VALUES LESS THAN (735417) ENGINE = InnoDB,
 PARTITION 03_07 VALUES LESS THAN (735418) ENGINE = InnoDB,
 PARTITION 04_07 VALUES LESS THAN (735419) ENGINE = InnoDB,
 PARTITION 05_07 VALUES LESS THAN (735420) ENGINE = InnoDB,
 PARTITION 06_07 VALUES LESS THAN (735421) ENGINE = InnoDB,
 PARTITION 07_07 VALUES LESS THAN (735422) ENGINE = InnoDB) */

mysql> explain partitions SELECT * FROM alert WHERE occurred >= '2013-07-02' and occurred <= '2013-07-04';
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | partitions        | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | alert | 02_07,03_07,04_07 | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+

然后你需要自己管理删除和创建分区。

答案 1 :(得分:0)

实际上,问题是如果密钥中的所有列都没有包含在散列函数中,则无法在分区表上定义PRIMARY或UNIQUE键。

一种可能的“修复”方法是从KEY定义中删除“PRIMARY”关键字。

问题是MySQL在声明一个UNIQUE或PRIMARY键时必须强制执行唯一性。并且为了强制执行,MySQL需要能够检查密钥值是否已经存在。 MySQL使用分区函数来确定找到特定密钥的分区,而不是检查每个分区。