【问题标题】:MYSQL: Partitioning Table keeping id uniqueMYSQL:分区表保持ID唯一
【发布时间】:2015-05-20 04:55:27
【问题描述】:

我们正在使用具有如下架构的表:-

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 行将位于不同的分区中。问题是当我们将其中一个的存档列值更新为另一个以将其中一行移动到存档分区时,它将不允许我们更新给出“重复错误”的条目。

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

【问题讨论】:

  • 为什么你的id会被复制?
  • @pala_ 因为 id 和 archive 必须是主键组合才能分区工作,因此 id 可以为不同的存档列值 0 和 1 复制。
  • ...您仍然可以在 id 上拥有唯一索引
  • @pala_ 如果我在 id 上添加唯一约束,那么我会收到错误,即分区列也应该是唯一索引的一部分。所以,它也帮不了我……
  • 啊。那么您需要使用序列表来生成 ID。您可以使用before insert 触发器自动添加它

标签: mysql partitioning database-partitioning


【解决方案1】:

很遗憾,

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 如此令人沮丧(特别是它缺乏对外键的支持),我建议不要完全使用它,直到表变得如此之大以至于它成为一个真正的问题。

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多