mysqldump表没有转储主键

时间:2009-06-19 15:42:25

标签: mysql mysqldump load-data-infile

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

这些表每个都有数百万条记录,它们在两台服务器上的原因是因为它们有多大。任何表格的改变和分页都会给我们带来太大的性能损失。

因为它们位于生产环境中,所以我无法以现有服务器上的任何方式更改它们。

问题是主键是一个唯一的自动递增字段,因此存在交叉点。

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

此时看起来我需要修改数据库结构,以便将主键的校验和或哈希用作实际上应该是唯一的两个唯一字段的组合...我真的不喜欢我想这样做。

帮助!

10 个答案:

答案 0 :(得分:24)

如果你不关心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

答案 1 :(得分:13)

为了解决这个问题,我查了一下这个问题,找到@ pumpkinthehead的答案,并意识到我们需要做的就是找到+用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'),

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

答案 2 :(得分:11)

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

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

> CREATE VIEW myView AS
  SELECT name, email FROM users

编辑:啊,我明白了,我不确定那时是否有其他办法。

答案 3 :(得分:6)

  1. 克隆你的桌子
  2. 删除克隆表中的列
  3. 转储没有结构的克隆表(但使用-c选项获取完整的插入)
  4. 导入您想要的地方

答案 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]*,不会取代你真正想要的东西。

希望能有所帮助。

答案 5 :(得分:3)

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';

为了增加功能,您可以在接收表上设置插入触发器,在插入之前为触发行设置新的主键,从而使用常规转储并仍然清除您的PK。没有经过测试,但对此感到非常自信。

答案 6 :(得分:2)

使用虚拟临时主键:

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

答案 7 :(得分:0)

吉米是走在正确的轨道上。

这是自动增量键是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)

下进行。

答案 8 :(得分:0)

我一直在使用的解决方案是只对我导出的数据进行常规SQL导出,然后使用RegEx find& replace编辑器从insert语句中删除主键。我个人使用Sublime Text,但我确信TextMate,Notepad ++等也可以这样做。

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

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

答案 9 :(得分:0)

我喜欢临时餐桌路线。

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行的情况下,它也需要花费几秒钟的时间才能运行,但行之有效。