3

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

我尝试了这个声明(哈希函数使用对分区数量取模来计算哪个分区获取数据)。这样可以确保每天使用 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;

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

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

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

有任何想法吗?

4

2 回答 2

2

原因是要对日期字段进行分区并按范围查询,您必须使用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 |
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+

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

于 2013-06-28T11:59:50.037 回答
0

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

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

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

于 2013-06-27T20:55:15.550 回答