MySQL使用分区并保持主键不变

时间:2013-02-05 11:44:21

标签: mysql primary-key partitioning

我正在使用MySQL 5.5,我在生产中有一个存储客户交易的现有表。该表的简化版本是:

CREATE TABLE transactions (
  id INT NOT NULL AUTO_INCREMENT,
  description CHAR(100),
  posted DATE,
  PRIMARY KEY (id)
) ENGINE=MyISAM

我们正在探索在事务日期使用分区的想法,以便使使用日期过滤的报告执行得更快。由于MySQL Partitioning Keys documentation中解释的主键和分区的限制,以下尝试失败。

mysql> CREATE TABLE transactions (
    ->   id INT NOT NULL AUTO_INCREMENT,
    ->   description CHAR(100),
    ->   posted DATE,
    ->   PRIMARY KEY (id)
    -> ) ENGINE=MyISAM
    -> PARTITION BY HASH(MONTH(posted)) PARTITIONS 12;
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function

可能的解决方法如下:

CREATE TABLE transactions (
  id INT NOT NULL AUTO_INCREMENT,
  description CHAR(100),
  posted DATE,
  PRIMARY KEY (id, posted)
) ENGINE=MyISAM
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12;

另一种解决方法是:

CREATE TABLE transactions (
  id INT NOT NULL AUTO_INCREMENT,
  description CHAR(100),
  posted DATE,
  KEY (id)
) ENGINE=MyISAM
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12;

在这两种解决方法中,数据库不会停止具有相同ID但发布日期不同的多个记录的情况。有没有办法在发布的字段上使用分区并保持原始的唯一约束?

1 个答案:

答案 0 :(得分:3)

我一直面临同样的“问题”,我找到的一个解决方法是将我的桌子分成两部分,在你的情况下会产生类似的结果:

CREATE TABLE transactions (
  id INT NOT NULL AUTO_INCREMENT,
  description CHAR(100),
  PRIMARY KEY (id)
) ENGINE=MyISAM;

另一个:

CREATE TABLE transactions_date (
  id INT NOT NULL,
  posted DATE
) ENGINE=MyISAM
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12;

显而易见的问题是,您必须向应用程序添加一些额外的逻辑,例如在使用SELECT语句时需要获取两个表以检索所有数据。您可以使用triggers来帮助您完成与INSERTUPDATEDELETE相关的任务。

只是一个注释DATEDATETIME列中使用partition pruning可以从中受益的唯一功能是:{{1 },YEAR()TO_DAYS()(最后一个仅在MySQL 5.5之后可用)。