MySQL服务器版本:5.6.17 我有两张桌子:
vatbands:
`vatbands_id` INT(11) UNSIGNED NOT NULL,
`client_id` INT(11) UNSIGNED NOT NULL COMMENT 'Customer ID',
`code` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL,
PRIMARY KEY (`vatbands_id`, `code`, `client_id`),
INDEX `vatcode_vatbands` (`code` ASC, `client_id` ASC)
ENGINE = InnoDB;
vatbands中的1行:
INSERT INTO `vatbands` (`client_id`, `code`) VALUES ('1', 'A');
项目:
`client_id` INT(11) UNSIGNED NOT NULL,
`vatcode` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL DEFAULT 'A',
PRIMARY KEY (`item_id`, `client_id`),
INDEX `vatcode_item` (`vatcode` ASC, `client_id` ASC),
CONSTRAINT `vatcode_item`
FOREIGN KEY (`vatcode` , `client_id`)
ENGINE = InnoDB;
插入子(项)表:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');
当我尝试插入我的items表而没有指定vatcode
我得到外键约束失败时:
Cannot add or update a child row: a foreign key constraint fails (`mydb`.`item`, CONSTRAINT `vatcode_item` FOREIGN KEY (`vatcode`, `client_id`) REFERENCES `vatbands` (`code`, `client_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
为什么这样,我认为指定vatcode
的默认值会允许它继续(只要该行存在)?
我查看了InnoDB手册:
14.6.6 InnoDB和FOREIGN KEY约束
InnoDB表的外键的引用操作受制于 以下条件:
虽然MySQL服务器允许SET DEFAULT,但它被拒绝为 InnoDB无效。
这是它失败的原因吗?
更新
如果我直接使用PHP输入值:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');
约束按预期成功。
答案 0 :(得分:1)
外键的SET DEFAULT
子句与插入子表无关。它声明如果删除或更新父表中引用的行,如何处理子表中的从属行。
示例:如果员工属于某个部门,并且该部门被删除,员工是否也应被解雇?或者他们应该被重新分配到其他一些"默认"部?
我测试了您的示例,我发现它工作正常,但您必须至少指定父表中存在的client_id
。
mysql> insert into items (client_id) values (1);
Query OK, 1 row affected (0.00 sec)
我还注意到你的密码输入(code,client_id)是非唯一密钥。它应该是子表的外键引用的主键或唯一键。事实上,当我使用MySQL 5.7里程碑版本进行测试时,我甚至无法创建items
表,因为在这方面显然MySQL的新版本比旧版本更严格。所以我必须让你的钥匙成为主键。然后测试工作。
答案 1 :(得分:0)
我能让它工作的唯一方法是使用PHP插入默认值。
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');
如果有人有更好的方法可以解决这个问题,请不要犹豫评论,我更喜欢纯粹的MySQL方法。
答案 2 :(得分:0)
如果您使用:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');
您不是插入NULL而是空字符串。
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', NULL);
将起作用