简体   繁体   English

澄清-默认外键约束-InnoDB

[英]Clarification - Default Foreign Key Constraints - InnoDB

MySQL Server version: 5.6.17 I have two tables: MySQL服务器版本:5.6.17我有两个表:

vatbands: 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;

1 row in vatbands: 宽带1行:

INSERT INTO `vatbands` (`client_id`, `code`) VALUES ('1', 'A');

items: 项目:

`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;

Inserting into child (item) table: 插入子表(项目):

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');

When I try to insert into my items table without specifying a vatcode i get foreign key constraint failure: 当我尝试在未指定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)

Why is this, I thought specifying a default value for the vatcode would allow this to continue (as long as the row exists)? 为什么会这样,我认为为vatcode指定默认值将允许它继续(只要该行存在)?

I have checked the InnoDB manual: 我已经检查了InnoDB手册:

14.6.6 InnoDB and FOREIGN KEY Constraints 14.6.6 InnoDB和外键约束

Referential actions for foreign keys of InnoDB tables are subject to the following conditions: InnoDB表的外键的引用操作必须满足以下条件:

While SET DEFAULT is allowed by the MySQL Server, it is rejected as invalid by InnoDB. 虽然MySQL服务器允许使用SET DEFAULT,但InnoDB拒绝它为无效。

Is this the reason it is failing? 这是失败的原因吗?

UPDATE: 更新:

If i input a value directly using PHP: 如果我直接使用PHP输入值:

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');

The constraint succeeds as expected. 约束按预期成功。

The SET DEFAULT clause for a foreign key has nothing to do with inserting to the child table. 外键的SET DEFAULT子句与插入子表无关。 It declares what to do with dependent rows in the child table if the referenced row in the parent table is deleted or updated. 如果删除或更新了父表中的引用行,它将声明如何处理子表中的相关行。

Example: If an employee belongs to a department, and the department is deleted, should the employee be fired as well? 示例:如果某个员工属于某个部门,并且删除了该部门,是否也应解雇该员工? Or should they be reassigned to some other "default" department? 还是应该将它们重新分配给其他“默认”部门?

I tested your example, and I find that it works fine, but you must specify at least a client_id that exists in the parent table. 我测试了您的示例,发现它可以正常工作,但是您必须至少指定父表中存在的client_id

mysql> insert into items (client_id) values (1);
Query OK, 1 row affected (0.00 sec)

I also notice that your key in vatbands on (code,client_id) is a non-unique key. 我还注意到,您在(code,client_id)上的vatbands中的密钥是非唯一密钥。 It should really be a primary key or unique key to be referenced by a foreign key of a child table. 它实际上应该是子表的外键引用的主键或唯一键。 In fact, when I test with MySQL 5.7 milestone release, I can't even create the items table because apparently in this regard the new version of MySQL is more strict than older versions. 实际上,当我使用MySQL 5.7里程碑版本进行测试时,我什至无法创建items表,因为显然在这方面,新版本的MySQL比旧版本更严格。 So I had to make your key a primary key. 因此,我必须将您的钥匙设为主钥匙。 Then the test worked. 然后测试成功了。

The only way I could get this to work is inserting a default using PHP. 我可以使它起作用的唯一方法是使用PHP插入默认值。

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');

If anyone has any better ways of resolving this please don't hesitate to comment, I would much prefer a pure MySQL method. 如果有人有更好的解决方案,请随时发表评论,我更喜欢纯MySQL方法。

If you use: 如果您使用:

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');

You are not inserting NULL but an empty string. 您不是要插入NULL而是一个空字符串。

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', NULL);

will work 将工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM