我想创建一个分区表,它将填充数亿条记录。如何使用分区如何将特定日期的记录放入一个分区,然后将第二天放入另一个分区等等。然后在九十多天后我可以从最旧的分区中删除旧数据。
我尝试了这个声明(哈希函数使用模数来计算分区数量来计算哪个分区获取数据)。这确保了每天使用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
列添加到主键,如果选择日期范围,则似乎会触及所有分区,这不是我想要的。
有什么想法吗?
答案 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使用分区函数来确定找到特定密钥的分区,而不是检查每个分区。