【问题标题】:How do I add a unique index on a field in a partitioned MySQL DB?如何在分区 MySQL 数据库中的字段上添加唯一索引?
【发布时间】:2011-06-21 01:34:14
【问题描述】:

我有一个表 foo,它由“created_at”分区,主键为 (id,created_at)。即:

CREATE TABLE `foo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `bar_id` int(11) DEFAULT NULL,
   ...

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (TO_DAYS(created_at))
(PARTITION p0 VALUES LESS THAN (733712) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (733773) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (733832) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (733893) ENGINE = InnoDB,
...
)

如何创建唯一索引以使bar_id 在所有分区中都是唯一的?如果我尝试类似:

CREATE UNIQUE INDEX some_index USING BTREE ON foo (bar_id);

我收到错误:

ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function

但是,如果我在构建索引时包含分区函数(idcreated_at),那么我最终得到的索引不能保证 bar_id 是唯一的。

更新

我应该提到我已经在桌子上有一个主键:

PRIMARY KEY (`id`,`created_at`)

另外,bar_id 可以为 NULL。

【问题讨论】:

  • 嘿,你找到办法了吗?我正在努力解决完全相同的问题。我什至不明白为什么分区键必须是唯一键的一部分。无法理解它。
  • @varunl,我也有同样的问题。我需要使用start datatime 字段作为分区键,并使用id 作为主键,但我必须将其他字段作为唯一键,这些字段确实需要是唯一的。

标签: sql mysql indexing unique


【解决方案1】:

错误消息本身就说明了问题。请阅读说明书, http://dev.mysql.com/doc/refman/5.5/en/partitioning-limitations-partitioning-keys-unique-keys.html

“规则是:分区表的分区表达式中使用的所有列必须是该表可能具有的每个唯一键的一部分。简单来说,表上的每个唯一键都必须使用表分区中的每一列表达。”

【讨论】:

【解决方案2】:

创建一个主键。

来自MySQL docs 关于分区:用于分区表达式的任何列都必须是表的主键(如果有的话)或(第一个)唯一键(如果它有唯一键但没有主键)的一部分.否则,您将看到错误消息“主键需要包含分区函数中的所有字段”。

如果表没有主键,但有一个或多个唯一键,则分区表达式中使用的任何列都必须是(第一个)唯一键的一部分。

【讨论】:

  • 我应该提到我在桌子上已经有一个主键:PRIMARY KEY (id,created_at)。此外,bar_id 可以为 NULL。
【解决方案3】:

这可以通过存储唯一bar_id 的辅助表和插入前触发器来完成。

【讨论】:

  • 这是一个有趣的方法。不幸的是,这意味着我需要编写一个例程(或更多)来处理 bar_id 更新为 NULL 或更改 foo 中给定行的情况,对吗?似乎有很多开销,这让我相信一定有一个更简单的解决方案。
猜你喜欢
  • 2012-12-04
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多