我有一个表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
但是,如果我在构建索引时包含分区函数(id
,created_at
),那么我最终得到的索引不能保证bar_id是唯一的。
更新
我应该提到我桌上已经有一个主键:
PRIMARY KEY (`id`,`created_at`)
另外,bar_id可以为NULL。
答案 0 :(得分:2)
错误消息本身解释了问题。请阅读手册, http://dev.mysql.com/doc/refman/5.5/en/partitioning-limitations-partitioning-keys-unique-keys.html
“规则是:分区表的分区表达式中使用的所有列必须是表可能具有的每个唯一键的一部分。简单来说,表上的每个唯一键必须使用表的分区中的每一列表述“。
答案 1 :(得分:0)
创建主键。
来自MySQL docs分区:用于分区表达式的任何列必须是表的主键(如果有的话)或(第一个)唯一键的一部分(如果它具有唯一键但没有主键)键)。否则,您将看到错误消息“A PRIMARY KEY需要包括分区函数中的所有字段”。
如果表没有主键,但确实有一个或多个唯一键,则分区表达式中使用的任何列都必须是(第一个)唯一键的一部分。
答案 2 :(得分:0)
这可以通过辅助表来完成,以存储唯一的bar_id
和插入前触发器。