【问题标题】:Foreign keys - temporarily bypass?外键 - 暂时绕过?
【发布时间】:2010-04-30 19:05:14
【问题描述】:

我刚刚开始了解数据库设计(mySQL / innoDB)中外键的优点,我想知道在执行特定删除查询时是否有任何方法可以暂时绕过外键,只在父表中删除,而不是来自链接的子表。

谢谢

【问题讨论】:

  • 如果您只想在父表中删除 - 链接的子表不应链接。 但是您可以将子表的外键设置为“ON DELETE SET NULL”,这会将项目保留在子表中,但它们将不再包含对已删除父表项的引用。

标签: mysql database-design foreign-keys


【解决方案1】:

甚至不要考虑这样做,它会导致您的数据库出现数据完整性问题。这是一个非常糟糕的主意。外键的全部目的是阻止人们做这样的事情!

【讨论】:

  • 这是我等着看的回复。
【解决方案2】:

您可以在外键上使用 ON DELETE SET NULL 子句。这将允许您删除父表中的行。子表中引用父表中已删除行的行将外键列设置为NULL。

就我个人而言,我从来没有真正需要过这个功能。

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

【讨论】:

  • 很遗憾您选择了错误的答案。这真是一个非常糟糕的主意。
  • 是的,这通常是个坏主意。但我可以想象这很有用的场景。不过,大多数有用的场景都应该使用关系表来解决。
【解决方案3】:

外键应该始终保持数据库一致。因此,将外键放在数据库中并仍然删除引用的行是违反外键的想法......

虽然……在一种情况下暂时打破这些约束可能是有意义的:在交易期间。重要的是让数据库在事务之前和之后保持一致,不要让任何其他数据库用户看到不一致的数据,但是在事务期间并且仅在执行事务的会话中,暂时的不一致不会受到伤害。 SQL 允许这样做:您可以定义一些可延迟的外键(有时还有其他约束),并请求延迟执行它们到事务结束。

这样,您可以对数据库进行一组复杂的更改,甚至删除一些仍然在其他表中引用的行,并且仍然使数据库保持一致并结束事务。其他数据库用户甚至不会看到临时的不一致。

更新: MySQL 似乎不支持延迟约束。所以这个答案可能不是很有用。

【讨论】:

    【解决方案4】:

    您始终可以发出命令来禁用特定键。除此之外,我没有办法绕过约束。我猜您正在执行一些批量加载操作并且出于性能原因需要禁用密钥?

    【讨论】:

    • 如果他尝试在现在有孤立记录的子表上启用外键怎么办?我认为如果他计划启用缺少父记录的约束,他仍然必须删除子记录。
    • 见我上面的编辑。他可能正在执行一些大规模的批量加载,在这种情况下,出于性能原因,删除所有键/索引/约束,加载数据,然后运行一些程序以确保没有任何事情发生,然后重新启用所有内容,这可能是有益的。
    【解决方案5】:

    编辑:DISABLE KEYS 不绕过外键检查,仅绕过唯一键检查。

    要删除外键约束,请使用:

    ALTER TABLE <tablename> DROP FOREIGN KEY <constraintname>;
    

    那么要恢复约束,需要在另一个ALTER TABLE语句中重新声明外键约束。

    详情请见http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

    但我同意@HLGEM,我给他的答案+1。如果您真的需要这样做,请仔细考虑。如果您保留外键约束,大多数任务实际上更容易

    您可以声明具有级联效果的外键,以将子表值设置为 NULL 或 DEFAULT 值,以便您可以删除父行。

    【讨论】:

      猜你喜欢
      • 2016-04-16
      • 2015-06-04
      • 1970-01-01
      • 2014-04-01
      • 2012-06-17
      • 2011-01-19
      • 2012-07-23
      • 1970-01-01
      • 2017-04-21
      相关资源
      最近更新 更多