【问题标题】:Can you automatically create a mysqldump file that doesn't enforce foreign key constraints?你能自动创建一个不强制外键约束的 mysqldump 文件吗?
【发布时间】:2011-01-26 15:27:28
【问题描述】:

当我在我的数据库上运行 mysqldump 命令然后尝试导入它时,它会失败,因为它尝试按字母顺序创建表,即使它们可能有一个外键来引用文件中稍后的表。 documentation 中似乎没有任何内容,我发现像 this 这样的答案说要在创建文件后更新文件以包含:

set FOREIGN_KEY_CHECKS = 0;
...original mysqldump file contents...
set FOREIGN_KEY_CHECKS = 1;

有没有办法自动设置这些行或以必要的顺序导出表格(无需手动指定所有表格名称,因为这可能很乏味且容易出错)?我可以将这些行包装在脚本中,但想知道是否有一种简单的方法可以确保我可以转储文件,然后在不手动更新的情况下导入它。

【问题讨论】:

    标签: mysql foreign-keys mysqldump data-import


    【解决方案1】:

    4.1.1 版本开始,MySQL 包含的mysqldump 命令默认生成一个关闭外键检查的脚本。转储文件顶部附近包含以下行:

    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    

    /*!40014 ... */ 语法是 conditional comment,将在 MySQL 4.0.14 及更高版本上执行。旧的外键检查设置在转储文件末尾恢复:

    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    

    请注意,条件 cmets 是 interpreted by the the client(而不是服务器)。如果您使用不支持它们的客户端加载转储文件,则不会禁用外键检查,您可能会遇到错误。为获得最佳效果,我建议使用官方 mysql 命令行客户端加载转储文件:

    mysql -hserver -uuser -p database < dumpfile.sql
    

    还值得注意的是,如果 mysqldump 使用 --compact 选项运行,则转储文件中将省略禁用和重新启用外键检查的命令。

    【讨论】:

    • 是的,我确实在文件中看到了这一点。尝试导入此文件的另一个人在外键行上遇到错误,并认为这是由于创建顺序造成的。
    • 这如何回答了这个问题? Tai 说他在文件中遇到了这些 cmets 错误,那么问题是如何解决的?
    • 这是一个公认的答案吗?它绝对不符合提出的问题:/
    • 我的问题是“--compact”,非常感谢!
    【解决方案2】:

    小心。 出于某种原因,如果使用了 --compact 选项,mysqldump 不会写入 FOREIGN_KEY_CHECKS=0。

    Ciao.

    【讨论】:

    • 原因是--compact 包含--skip-comments 所以应该使用--compact 而不是--skip-add-drop-table --skip-add-locks --skip-disable-keys --skip-set-charset
    • 您实际上也可以 --skip-cmets。手册说--compact“启用--skip-add-drop-table、--skip-add-locks、--skip-cmets、--skip-disable-keys和--skip-set-charset options”,但显然 --compact 还删除了除此之外的一些其他输出——例如 FOREIGN_KEY_CHECKS 语句。
    【解决方案3】:

    如果您在导出 SQL 时使用 phpMyAdmin,请选择 自定义导出方法。然后在复选框选项中,单击“禁用外键检查”。导出的 SQL 语句将分别在输出文件的开头和结尾处禁用和启用外键检查。

    这不是“自动”的,但您不必为每次导出都自己编写语句。

    【讨论】:

    • 哇!反对建议一种比所要求的更容易工作的替代解决方案
    • 那是因为“更容易”是非常主观的(例如,我根本没有用它)而且它实际上并没有回答问题。
    • +1 对 PhpMyAdmin 用户绝对有用。其他人都可以主观地忽略它,或者非常主观地否决它:)
    【解决方案4】:

    如果您将--compact 用作您的mysqldump 命令之一,则可能会发生这种情况。 --compact 包括--skip-comments 所以应该使用--compact 而不是--skip-add-drop-table --skip-add-locks --skip-disable-keys --skip-set-charset

    【讨论】:

      【解决方案5】:

      注意您使用的 MySQL 客户端,使用 mysql 命令,没问题。倾倒:

      % mysqldump -u ocp6 -pocp6 ocp6 --single-transaction --result-file=dump.sql 
      

      恢复:

      % mysql -u ocp6 -pocp6 ocp6 < dump.sql
      

      一切都很好。

      使用另一个 MySQL 客户端(在我的情况下为mycli)来恢复转储文件:

      mysql ocp6@:(none)> \. dump.sql
      […]
      (1005, 'Can\'t create table `ocp6`.`composition` (errno: 150 "Foreign key constraint is incorrectly formed")')
      

      我假设mycli 不理解conditional comments

      【讨论】:

        【解决方案6】:

        使用--single-transaction 意味着在一个事务中完成所有操作。该选项不能忽略格式错误的Foreign key constraint。 在任何事务中,任何错误都将停止继续执行查询。您的问题是您有一个不存在的表的Foreign key constraint

        【讨论】:

          猜你喜欢
          • 2017-01-24
          • 2013-11-22
          • 2016-02-18
          • 1970-01-01
          • 2019-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-29
          相关资源
          最近更新 更多