【问题标题】:mysqldump table without dumping the primary keymysqldump 表而不转储主键
【发布时间】:2010-11-04 08:33:40
【问题描述】:

我有一张表分布在运行 MySql 4 的两台服务器上。我需要将它们合并到一台服务器中以用于我们的测试环境。

这些表实际上每个都有数百万条记录,它们位于两台服务器上的原因是因为它们非常庞大。对表的任何更改和分页都会给我们带来太大的性能损失。

因为它们在生产环境中,所以我不可能在它们现有的服务器上以任何方式更改它们。

问题是主键是一个唯一的自增字段,所以会有交集。

我一直在试图弄清楚如何使用 mysqldump 命令忽略某些字段,但是 --disable-keys 只是改变了表,而不是完全摆脱了键。

在这一点上,我似乎需要修改数据库结构以利用主键的校验和或哈希作为实际上应该是唯一的两个唯一字段的组合......我真的不'不想这样做。

救命!

【问题讨论】:

    标签: mysql mysqldump load-data-infile


    【解决方案1】:

    为了解决这个问题,我查了这个问题,找到了@pumpkinthehead的答案,发现我们需要做的就是find+replace每行的主键为NULL,这样mysql就会使用默认的auto_increment值.

    (your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql

    原始输出:

    INSERT INTO `core_config_data` VALUES
        (2735,'default',0,'productupdates/configuration/sender_email_identity','general'),
        (2736,'default',0,'productupdates/configuration/unsubscribe','1'),
    

    转换后的输出:

    INSERT INTO `core_config_data` VALUES
        (NULL,'default',0,'productupdates/configuration/sender_email_identity','general'),
        (NULL,'default',0,'productupdates/configuration/unsubscribe','1'),
    

    注意:这仍然是一个 hack;例如,如果您的自动增量列不是第一列,但 99% 的时间都解决了我的问题,它将失败。

    【讨论】:

    • 如果您使用支持正则表达式替换的文本编辑器,您可以查找VALUES \([0-9]+并替换为VALUES \(NULL,此正则表达式解决方案也可以扩展用于不自动增量的表在第一列。
    • 这可能是一个 hack,但它确实是正确的解决方案。
    【解决方案2】:

    如果您不关心 auto_increment 列的值是什么,那么只需加载第一个文件,重命名表,然后重新创建表并加载第二个文件。最后,使用

    INSERT newly_created_table_name (all, columns, except, the, auto_increment, column)
           SELECT all, columns, except, the, auto_increment, column
             FROM renamed_table_name
    

    【讨论】:

    • 看起来很有希望,我会开始尝试这个。
    • 我有一个引用主键的外键字段。该解决方案是否保持这种参照完整性?看起来不像。
    • 不,不会。它改变了主键。
    • 作为替代方案,如果您使用 phpmyadmin 或 mysql workbench 之类的工具,您可以执行 mysql 转储并从结果中排除某些列。
    【解决方案3】:

    您可以创建一个没有主键列的表视图,然后在该视图上运行 mysqldump。

    因此,如果您的表“用户”包含以下列:id、name、email

    > CREATE VIEW myView AS
      SELECT name, email FROM users
    

    编辑:啊,我明白了,我不确定是否还有其他方法。

    【讨论】:

    • 不在 mysql 4 上 :(。我知道,伤心 :(.
    • 根据表的大小,您可以创建一个临时副本(没有 PK)而不是创建一个视图。
    • 表在数百万条记录范围内。
    • 仅供参考尝试在 phpmyadmin 中导出视图将导致没有行。
    【解决方案4】:
    1. 克隆您的表
    2. 删除克隆表中的列
    3. 转储没有结构的克隆表(但使用 -c 选项获取完整插入)
    4. 根据需要导入

    【讨论】:

      【解决方案5】:

      这是一个彻头彻尾的痛苦。我通过运行类似

      的方法来解决这个问题
      sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql 
      

      在转储上去掉主键然后

      sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql
      

      除了主键之外的所有列。当然,您必须小心 ([0-9]*, 不会替换您真正想要的任何内容。

      希望对某人有所帮助。

      【讨论】:

      • 我不得不从正则表达式中删除 i 标志,否则,这就像一个魅力!谢谢!
      • 使用mysqldump --complete-insert ...时不需要第二条语句。
      【解决方案6】:
      SELECT null as fake_pk, `col_2`, `col_3`, `col_4` INTO OUTFILE 'your_file'
      FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
      LINES TERMINATED BY '\n'
      FROM your_table;
      
      LOAD DATA INFILE 'your_file' INTO TABLE your_table
      FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
      LINES TERMINATED BY '\n';
      

      为了增加趣味性,您可以在接收表上设置 before insert 触发器,在插入发生之前为到达行设置新的主键,从而使用常规转储并仍然清除您的 pk。未经测试,但对它很有信心。

      【讨论】:

        【解决方案7】:

        使用虚拟临时主键:

        通常使用mysqldump--opts -c。例如,您的主键是“id”。 编辑输出文件并在表结构中添加一行“dummy_id”,其类型与“id”相同(当然不是主键)。然后修改INSERT 语句并将'id' 替换为'dummy_id'。导入后,删除“dummy_id”列。

        【讨论】:

          【解决方案8】:

          jimyi 是在正确的轨道上。

          这是自动增量键是 PITA 的原因之一。一种解决方案是不删除数据,而是添加数据。

          CREATE VIEW myView AS
          SELECT id*10+$x, name, email FROM users
          

          (其中 $x 是唯一标识原始数据库的单个数字)在源数据库上创建视图(您暗示这可能是不可能的)或使用像 Autocracy 描述的提取例程或将数据加载到暂存中测试盒上的表格。

          或者,不要在测试系统上创建表 - 而是为 src 数据放入单独的表,然后创建一个从它们两者中获取的视图:

          CREATE VIEW users AS
          (SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b)
          

          C.

          【讨论】:

          • 我不明白创建视图有什么帮助,因为 mysqldump 不输出视图数据,只输出 CREATE VIEW 语句,所以你没有进一步的进展。如果您只是使用视图然后创建一些临时表,那么视图是多余的。如果您随后打算使用 select .. into outfile,那么再一次,该视图是多余的。我错过了什么?
          【解决方案9】:

          我一直在使用的解决方案是对我正在导出的数据进行常规 SQL 导出,然后使用 RegEx 查找和替换编辑器从插入语句中删除主键。我个人使用 Sublime Text,但我确信 TextMate、Notepad++ 等也可以做到。

          然后,我只需将查询复制粘贴到 HeidiSQL 的查询窗口或 PHPMyAdmin 中,即可运行查询数据应该插入到哪个数据库。如果有 LOT 数据,我将插入查询保存到 SQL 文件并改用文件导入。复制和粘贴大量文本通常会使 Chrome 冻结。

          这听起来像是很多工作,但我很少在导出和导入之间使用超过几分钟的时间。可能比我在接受的解决方案上使用的要少得多。我已经在几十万行上使用了这种解决方法而没有问题,但我认为当你达到数百万时它会出现问题。

          【讨论】:

            【解决方案10】:

            我喜欢临时表路由。

            create temporary table my_table_copy
            select * from my_table;
            
            alter table my_table_copy drop id;
            
            // Use your favorite dumping method for the temporary table
            

            与其他解决方案一样,这不是一个万能的解决方案(尤其是考虑到 OP 的数百万行),但即使在 10^6 行时,它也需要几秒钟才能运行但有效。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-02-02
              • 2011-08-05
              • 2012-08-15
              • 1970-01-01
              • 2017-12-04
              相关资源
              最近更新 更多