2

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

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

我们正在探索在交易日期上使用分区的想法,以使使用日期过滤的报告执行得更快。由于MySQL 分区键文档中解释的主键和分区限制,以下尝试失败。

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 但发布日期不同的多条记录的情况。有没有办法在发布的字段上使用分区并保持原始的唯一约束?

4

1 回答 1

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语句时需要获取两个表以检索所有数据。您可能可以使用触发器来帮助您完成与和相关INSERT的任务。UPDATEDELETE

请注意:在or列中使用分区修剪可以受益的唯一功能是:和(最后一个仅从 MySQL 5.5 开始可用)。DATEDATETIMEYEAR()TO_DAYS()TO_SECONDS()

于 2013-02-27T18:13:58.723 回答