如何对包含多个唯一键的MySQL表进行分区?

时间:2017-07-26 11:38:24

标签: mysql database partitioning

我有一个非常大的MySQL表,我想分区。该表的简化创建如下所示 -

CREATE TABLE `myTable` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `columnA` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `columnB` varchar(50) NOT NULL ,
  `columnC` int(11) DEFAULT NULL,
  `columnD` varchar(255) DEFAULT NULL,
  `columnE` int(11) DEFAULT NULL,
  `columnF` varchar(255) DEFAULT NULL,
  `columnG` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_B` (`columnB`),
  UNIQUE KEY `UNIQ_B_C` (`columnB`,`columnC`),
  UNIQUE KEY `UNIQ_C_D` (`columnC`,`columnD`),
  UNIQUE KEY `UNIQ_E_F_G` (`columnE`,`columnF`,`columnG`)
  )

我想用columnA或id对我的表进行分区,但问题是MySQL手册说明了 -

  

换句话说,表上的每个唯一键都必须使用表格分区表达式中的每一列。

这意味着我无法在不更改模式的情况下对这两列中的表进行分区。例如,我考虑过将id添加到我所有的唯一键中,如此 -

CREATE TABLE `myTable` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `columnA` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `columnB` varchar(50) NOT NULL ,
  `columnC` int(11) DEFAULT NULL,
  `columnD` varchar(255) DEFAULT NULL,
  `columnE` int(11) DEFAULT NULL,
  `columnF` varchar(255) DEFAULT NULL,
  `columnG` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_B` (`columnB`,`id`),
  UNIQUE KEY `UNIQ_B_C` (`columnB`,`columnC`,`id`),
  UNIQUE KEY `UNIQ_C_D` (`columnC`,`columnD`,`id`),
  UNIQUE KEY `UNIQ_E_F_G` (`columnE`,`columnF`,`columnG`,`id`)
  )

我不介意这样做,除了它允许创建不应该创建的行。例如,根据我的原始架构,以下行插入将不会工作两次 -

  INSERT into myTable (columnC, columnD) VALUES (1.0,2.0)

但它适用于第二个模式,因为columnC和columnD本身不再形成唯一键。我已经考虑通过使用触发器来防止创建这样的行来解决这个问题,但是触发成本会降低(或超过)分区性能增益

已编辑:

有关此表格的一些其他信息:

  1. 表的记录超过1.2亿。
  2. 将Mysql 5.6.34版本与InnoDB Engine一起使用并在AWS RDS上运行。
  3. 此表中也没有其他索引。
  4. 由于存在大量数据和多个索引,因此插入和检索数据是一个昂贵的过程。
  5. timestamp和float数据类型没有唯一索引。它只是用于说明的示例表模式。我们的实际表格与上表类似。
  6.   

    除了分区我们必须改进哪些选项   表的性能不会丢失任何数据并维护   完整性约束。

1 个答案:

答案 0 :(得分:1)

  

如何对包含多个唯一键的MySQL表进行分区?

很抱歉,不要说。

另外,你不应该。请记住,对具有唯一键的表的UPDATEINSERT操作必须查询表,以确保键保持唯一。如果可以对表进行分区,那么唯一键不会内置到partititon表达式中,那么每次插入或更新都需要查询每个分区。这可能会使分区变得更糟,而不是无用。