MySQL:引用两个父项的外键

时间:2010-02-04 20:00:21

标签: mysql foreign-keys

有一个有趣的情况:我有一个从.name(子表)到b.name(父表)的外键。 b.name对它没有唯一约束,因此它可能包含重复值。

如果我将名称'bob'放入b.name 两次,然后将其放入a.name,我就无法删除或更新 实例表b中的'bob'。在这两种情况下,它都抱怨通过删除/更新表b中的行,将a.name链接到b.name的FKey将失败。

现在这是有道理的,但我希望能够告诉FKey只有在表b中有 no 其他实例'bob'时才会失败。因此,如果我在b.name中有多个'bob'实例,我可以更改/删除除最后一个之外的任何实例。

[请注意,明显并在b.name上添加唯一约束将不起作用,因为它会在我没写的应用程序中导致'未定义的行为']

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

直接来自http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

...Additionally, MySQL and InnoDB require that the referenced columns be indexed for performance. However, the system does not enforce a requirement that the referenced columns be UNIQUE or be declared NOT NULL.The handling of foreign key references to nonunique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only UNIQUE and NOT NULL keys....

那么,让你的FK与独特的价值观相关联,或者说谁会发生什么?

答案 1 :(得分:0)

据我记得,外键应该引用一个独特的实体。 在您的情况下,您需要在BEFORE触发器中实现所有逻辑,而不是使用外键

答案 2 :(得分:0)

如果你在b.name中放入'bob'两次,那么它就不再唯一地标识为表b中的行。

如果您的要求是b.name可以有重复值,那么您的表a需要使用更好的密钥(代理密钥或复合密钥)。

除了更新/删除问题之外,SELECT * FROM a join b on a.name = b.name之类的查询也无法正常工作。

答案 3 :(得分:0)

虽然您的情况远非最佳,甚至建议,但您可以绕过这样的外键检查:

SET FOREIGN_KEY_CHECKS = 0;
// do your dirty work here
SET FOREIGN_KEY_CHECKS = 1;

您必须按照帖子中的描述维护代码中的参照完整性。