更新:您应该改用@greenoldman 在下面的评论中建议的想法。创建一个带有触发器的布尔字段,以根据您的可为空字段是否为 NULL 来设置值,然后将布尔字段与定义唯一性的其他字段组合在唯一约束中。
如果您必须强制执行唯一约束但还需要在列上具有外键,那么我找到了解决此问题的方法,因此要求它可以为空。我的解决方案就是由此派生的,需要一点额外的空间。这是一个带有数字 id 字段的示例。
基本概念是您必须创建另一个不可为空的字段,该字段将具有可空字段的值,外键通过触发器复制到其中。然后将对不可为空的重复字段强制执行唯一约束。为此,您需要定义一个不可为空的字段,其默认值0
类似于:
ALTER TABLE `my_table` ADD `uniq_foo` int(10) UNSIGNED NOT NULL DEFAULT '0';
然后你只需要像这样定义一些触发器:
DROP TRIGGER IF EXISTS `my_table_before_insert`;
DELIMITER ;;
CREATE TRIGGER `my_table_before_insert` BEFORE INSERT ON `my_table`
FOR EACH ROW
BEGIN
SET NEW.uniq_foo = IFNULL(NEW.foo_id, 0);
END;;
DELIMITER ;
DROP TRIGGER IF EXISTS `my_table_before_update`;
DELIMITER ;;
CREATE TRIGGER `my_table_before_update` BEFORE UPDATE ON `my_table`
FOR EACH ROW
BEGIN
SET NEW.uniq_foo = IFNULL(NEW.foo_id, 0);
END;;
DELIMITER ;