2011-02-04 139 views
5

我有一个表foo,它被'created_at'分区,其主键为(id,created_at)。即:如何在分区MySQL数据库的字段中添加唯一索引?

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是唯一的。

UPDATE

我应该提到,我已经对表的主键:

PRIMARY KEY (`id`,`created_at`) 

此外,bar_id可以为NULL。

+2

嘿,你找出一个办法吗?我正在努力解决完全相同的问题。我甚至不明白为什么分区键必须是唯一键的一部分。无法理解它。 – varunl 2012-08-28 18:43:52

+0

@varunl,我也有同样的问题。我需要使用`start datatime`字段作为分区键,并使用'id`字段作为主键,但是我必须将其他字段作为UNIQUE KEY,这些字段确实需要是唯一的。 – shgnInc 2015-04-23 06:07:01

回答

0

创建一个主键。

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

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

+0

我应该提到我已经在表上有一个主键:PRIMARY KEY(`id`,`created_at`)。另外,bar_id可以是NULL。 – 2011-02-05 22:22:25

0

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

+0

这是一个有趣的方法。不幸的是,这意味着我需要编写一个例程(或更多)来处理bar_id更新为NULL或更改为foo中给定行的情况,是否正确?看起来像很多开销,这使我相信必须有一个更简单的解决方案。 – 2011-02-05 22:59:00

相关问题