对于具有mariaDb 10.4.10的mysql v8.0.18项目
我想在现有表格中添加多列的唯一约束
ALTER TABLE 'new_purchasseorder' ADD UNIQUE ('created', 'fk_customer_id', 'fk_removal_id', 'fk_recipient_id')
但不希望检查旧数据
类似的东西:
where id > 3869
我也尝试了SET FOREIGN_KEY_CHECKS=0;
,但在这种情况下也没有工作。
有可能吗?
答案 0 :(得分:0)
据我所知,您不能对唯一约束执行此操作,因为您已经发现,无论id
的值如何,这样的约束都会应用于整个表。一种解决方法可能是使用插入前触发器进行断言:
DELIMITER //
CREATE TRIGGER contacts_before_insert
BEFORE INSERT ON new_purchasseorder FOR EACH ROW
BEGIN
IF EXISTS (SELECT 1 FROM new_purchasseorder
WHERE created = NEW.created AND
fk_customer_id = NEW.fk_customer_id AND
fk_removal_id = NEW.fk_removal_id AND
fk_recipient_id = NEW.fk_recipient_id)
THEN
signal sqlstate '45000';
END IF;
END; //
DELIMITER ;
此插入触发器将导致将唯一索引定义为重复数据的所有插入插入均因错误而失败,从而有效地阻止了该插入。
更好的长期(且更轻松)的策略可能是修复旧数据,以便它可以满足唯一约束的要求。
答案 1 :(得分:0)
从8.0.13版本开始,MySQL支持功能关键部分-基本是表达式的索引。假设所有4列都不为空,则可以执行以下操作:
create unique index idx_new_purchaseorder on new_purchaseorder (
(
case when id > 3869
then concat_ws('$$', created, fk_customer_id, fk_removal_id, fk_recipient_id)
end
)
)
case
表达式对id
值进行过滤,并生成一个串联的字符串,该字符串对于符合该过滤器的行应该是唯一的。我使用一些奇特的字符来避免“假”重复。