MYSQL:分区表保持id唯一

时间:2015-05-20 04:55:28

标签: mysql partitioning database-partitioning

我们使用的表格如下所示: -

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"。

有人可以在这方面提供帮助吗?

1 个答案:

答案 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是这样的下行者(特别是它缺乏对外键的支持),我建议不要一直使用它,直到表变得如此之大以至于它成为一个真正的问题。