我创建了名为books
的下表:
CREATE TABLE IF NOT EXISTS `books` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我创建了另一个名为compare
的平板电脑来比较books
表中的任意两本书:
CREATE TABLE IF NOT EXISTS `compare` (
`id_1` BIGINT UNSIGNED NOT NULL,
`id_2` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id_1`,`id_2`),
FOREIGN KEY (`id_1`) REFERENCES books(`id`),
FOREIGN KEY (`id_2`) REFERENCES books(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
之前的工作符合预期,但我需要强制MYSQL仅允许compare
表中唯一的值组合。
例如,如果我在compare
表中有以下行:
id_1 | id_2
------------
1 | 2
我想强制MYSQL不允许我插入以下行:
id_1 | id_2
------------
2 | 1
所以我希望MYSQL只允许1,2
或2,1
。
答案 0 :(得分:2)
另一种方法是交换插入前触发器中的值以确保id_1< ID_2:
CREATE TRIGGER `compare_before_insert` BEFORE INSERT ON `compare` FOR EACH ROW
BEGIN
DECLARE t BIGINT;
IF(NEW.id_1 > NEW.id_2) THEN
SET t = NEW.id_1;
SET NEW.id_1 = NEW.id_2;
SET NEW.id_2 = t;
END IF;
END
这将允许您使用该键使这些对唯一。
答案 1 :(得分:1)
在MySQL中(至少在版本8之前),如果希望数据库强制执行约束,则需要使用触发器执行此操作。
delimiter $$
create trigger compare_insert_trigger before insert on compare
for each row
begin
if (exists (select 1
from compare c
where c.id2 = new.id1 and c.id1 = new.id2
)
) then
signal sqlsate '45000'
set message_text = 'Book pair already exists in compare';
end if;
end;$$
delimiter ;
当然,您仍然需要唯一约束。