这是我的多对多关系表:
Related:
-id
-id_postA
-id_postB
我想要这个:
例如,如果有一行 id_postA = 32 和 id_postB = 67
那么它必须忽略插入带有 id_postA = 67 AND id_postB = 32
的行。
最佳答案
一个选择是创建一个 unique index在两列上:
CREATE UNIQUE INDEX uk_related ON related (id_postA, id_postB);
然后使用 trigger 防止“按顺序反转重复” ,在 INSERT
和 UPDATE
上订购 id_postA
和 id_postB
:
CREATE TRIGGER order_uk_related
BEFORE INSERT -- Duplicate this trigger also for UPDATE
ON related -- As MySQL doesn't support INSERT OR UPDATE triggers
FOR EACH ROW
BEGIN
DECLARE low INT;
DECLARE high INT;
SET low = LEAST(NEW.id_postA, NEW.id_postB);
SET high = GREATEST(NEW.id_postA, NEW.id_postB);
SET NEW.id_postA = low;
SET NEW.id_postB = high;
END;
正如您在此 SQLFiddle 中看到的那样,第四次插入将失败,因为 (2, 1)
已经被触发器切换为 (1, 2)
:
INSERT INTO relation VALUES (1, null, null)
INSERT INTO relation VALUES (2, null, null)
INSERT INTO relation VALUES (3, 2, 1)
INSERT INTO relation VALUES (4, 1, 2)
基于函数的索引
在其他一些数据库中,您可以使用基于函数的索引。不幸的是,这在 MySQL ( Is it possible to have function-based index in MySQL? ) 中是不可能的。如果这是一个 Oracle 问题,你会写:
CREATE UNIQUE INDEX uk_related ON related (
LEAST(id_postA, id_postB),
GREATEST(id_postA, id_postB)
);
关于mysql - 如何避免这种重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16487240/