错误代码:1503:唯一索引必须包含表中的所有列。当存在唯一索引时如何对表进行分区?

问题描述 投票:0回答:1

列定义

ID 列是具有自动增量的主键,我们用它来维护池范围。

Serial 是唯一的,即使分区后也需要是唯一的。

产品的状态是一个值为 A 或 U 的枚举。

问题:

我想根据状态对表进行分区。大多数 SQL 查询基于主键或状态为 A 的序列号。当我尝试使用下面的查询创建分区时,它不起作用。

ALTER TABLE product
PARTITION BY LIST COLUMNS(status)
(
   PARTITION used VALUES IN ('U'),
   PARTITION used VALUES IN ('A')
);
Error Code : 1503: A Unique Index must include all columns in the table

谁能告诉我解决这个问题的正确方法?

mysql partitioning
1个回答
0
投票

您不能使用 ENUM - 分区表达式中不允许使用此数据类型。请改用带有 CHECK 约束的 CHAR(1)。

您不能将

serial
定义为具有相应索引的 UNIQUE,因为任何唯一索引都必须包含分区表达式中使用的所有列。请改用触发器。

主键必须包含

status
列(见上文)和
id
列作为前缀(自动增量所需)。如果您需要单独检查
id
唯一性,请相应地扩展触发器代码。

样品

创建表:

CREATE TABLE product (
    id BIGINT UNSIGNED AUTO_INCREMENT,
    `serial` VARCHAR(16) NOT NULL,
    status CHAR(1) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id, status),
    CHECK (status IN ('A', 'U'))
);

创建触发器:

CREATE TRIGGER tr1
BEFORE INSERT ON product
FOR EACH ROW 
BEGIN
    IF EXISTS ( SELECT NULL 
                FROM product 
                WHERE `serial` = NEW.`serial`
                ) THEN 
        SIGNAL SQLSTATE '45000' 
            SET MESSAGE_TEXT = 'The column ''serial'' must be unique.';
    END IF;
END
CREATE TRIGGER tr2
BEFORE UPDATE ON product
FOR EACH ROW 
BEGIN
    IF EXISTS ( SELECT NULL
                FROM product
                WHERE `serial` = NEW.`serial`
                  AND OLD.`serial` <> NEW.`serial`
                ) THEN 
        SIGNAL SQLSTATE '45000' 
            SET MESSAGE_TEXT = 'The column ''serial'' must be unique.';
    END IF;
END

更改表,创建分区:

ALTER TABLE product
PARTITION BY LIST COLUMNS(status)
(
   PARTITION used VALUES IN ('U'),
   PARTITION not_used VALUES IN ('A')
);

插入合法行:

INSERT INTO product (`serial`, status) VALUES ('ABC', 'A');
INSERT INTO product VALUES (DEFAULT, 'DEF', 'U', DEFAULT);

通过

serial
插入重复项 - 错误:

INSERT INTO product (`serial`, status) VALUES ('DEF', 'A');
The column 'serial' must be unique.

插入无效的

status
值 - 错误:

INSERT INTO product (`serial`, status) VALUES ('GHI', 'X');
Check constraint 'product_chk_1' is violated.

serial
更新为现有值 - 错误:

UPDATE product SET `serial` = 'ABC' WHERE `serial` = 'DEF';
The column 'serial' must be unique.

更新且

serial
不变 - 触发器允许:

UPDATE product SET created_at = NOW() + INTERVAL 1 DAY WHERE status = 'A';

见表格内容:

SELECT * FROM product;
id 连续剧 状态 创建于
2 防御 2023-12-21 06:07:14
1 ABC A 2023-12-22 06:07:14

查看单个分区内容:

SELECT * FROM product PARTITION (used);
id 连续剧 状态 创建于
2 防御 2023-12-21 06:07:14

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.