我们使用的表格如下所示: -
CREATE TABLE `user_subscription` (
`ID` varchar(40) NOT NULL,
`COL1` varchar(40) NOT NULL,
`COL2` varchar(30) NOT NULL,
`COL3` datetime NOT NULL,
`COL4` datetime NOT NULL,
`ARCHIVE` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
)
现在我们想在列ARCHIVE上进行分区。 ARCHIVE只能有2个值0或1,因此有2个分区。
实际上,在我们的案例中,我们使用分区作为档案流程。要进行分区,我们需要将ARCHIVE列作为主键的一部分。但这里的问题是2行可以具有相同的ID和不同的ARCHIVE列值。实际上这不是我们作为2行的主要问题将在不同的分区。问题是当我们将其中一个的归档列值更新为other以将其中一个行移动到归档分区时,那么它将不允许我们更新条目给出" Duplicate Error"。
有人可以在这方面提供帮助吗?
答案 0 :(得分:0)
不幸的是,
UNIQUE INDEX
(或PRIMARY KEY
)必须包含表格分区功能中的所有列
并且由于MySQL也不支持检查约束,我能想到的唯一丑陋的解决方法是通过触发器手动强制执行唯一性:
CREATE TABLE t (
id INT NOT NULL,
archived TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id, archived), -- required by MySQL limitation on partitioning
)
PARTITION BY LIST(archived) (
PARTITION pActive VALUES IN (0),
PARTITION pArchived VALUES IN (1)
);
CREATE TRIGGER tInsert
BEFORE INSERT ON t FOR EACH ROW
CALL checkUnique(NEW.id);
CREATE TRIGGER tUpdate
BEFORE UPDATE ON t FOR EACH ROW
CALL checkUnique(NEW.id);
DELIMITER //
CREATE PROCEDURE checkUnique(pId INT)
BEGIN
DECLARE flag INT;
DECLARE message VARCHAR(50);
SELECT id INTO flag FROM t WHERE id = pId;
IF flag IS NOT NULL THEN
-- the below tries to mimic the error raised
-- by a regular UNIQUE constraint violation
SET message = CONCAT("Duplicate entry '", pId, "'");
SIGNAL SQLSTATE "23000" SET
MYSQL_ERRNO = 1062,
MESSAGE_TEXT = message,
COLUMN_NAME = "id";
END IF;
END //
(fiddle)
MySQL's limitations on partitioning是这样的下行者(特别是它缺乏对外键的支持),我建议不要一直使用它,直到表变得如此之大以至于它成为一个真正的问题。