【问题标题】:MySQL: A foreign key referencing two parentsMySQL:引用两个父母的外键
【发布时间】:2011-01-13 06:00:07
【问题描述】:

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

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

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

[请注意,在 b.name 上添加唯一约束是行不通的,因为它会在我没有编写的应用程序中导致“未定义的行为”]

有什么想法吗?

【问题讨论】:

    标签: mysql foreign-keys


    【解决方案1】:

    直接来自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 与独特的价值观联系起来,或者谁来说会发生什么?

    【讨论】:

    • 不知道我是怎么错过的。谢谢。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果您在 b.name 中输入了两次 'bob',则它不再唯一标识为表 b 中的行。

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

      除了更新/删除问题之外,SELECT * FROM a join b on a.name = b.name 之类的查询也不会按预期工作。

      【讨论】:

      • 是的,谢谢。我的大问题是我们正在集成的应用程序是由第三方编写的,他们定义了数据库模式。然后我们将一些表添加到他们的数据库中,这就是我们搞砸的地方。是的,我知道这并不理想。 :-)
      • 几乎每个编程任务都不理想:P
      【解决方案4】:

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

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

      您必须按照帖子中的说明在代码中保持引用完整性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-04
        • 2020-12-18
        • 2011-01-11
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多