【发布时间】:2017-09-27 14:22:39
【问题描述】:
我有 4 个较大的 MYSQL 表。
每个都有大约 1000 万行。
这些表只包含一个唯一的 ID。
某些表可能包含其他表中的重复 ID。我只想将其中一个保留在最终的合并表中。
所以基本上我需要导出所有 4 个表并将它们组合成一个超过 4000 万行且没有重复的大表。
使用相对较大的文件来实现这一切的最佳方法是什么? 我在 phpmyadmin 中的导出/导入遇到了限制,因此可能必须从命令行执行此操作。
【问题讨论】:
我有 4 个较大的 MYSQL 表。
每个都有大约 1000 万行。
这些表只包含一个唯一的 ID。
某些表可能包含其他表中的重复 ID。我只想将其中一个保留在最终的合并表中。
所以基本上我需要导出所有 4 个表并将它们组合成一个超过 4000 万行且没有重复的大表。
使用相对较大的文件来实现这一切的最佳方法是什么? 我在 phpmyadmin 中的导出/导入遇到了限制,因此可能必须从命令行执行此操作。
【问题讨论】:
正如其他人提到的,MySQL 支持INSERT IGNORE... 的选项,这意味着尝试插入,但对于每一行,如果它与唯一键冲突(或导致另一个错误,如失败NOT NULL 或 FOREIGN KEY 检查),它只是跳过该行并继续插入下一行。
您可能知道 MySQL 附带的 mysqldump 工具。它可以选择使用INSERT IGNORE 语法导出数据。
您还需要省略 CREATE TABLE,因为如果您要将四个数据集导入同一个目标表,则不需要创建该表四次。
所以这是我的建议:
在您的一台服务器上,仅获取表定义。如果它们都相同,那么您从哪个服务器获取它并不重要:
mysqldump --no-data mydatabase mytable > create.sql
然后仅从您的四台服务器中的每台获取数据:
mysqldump --no-create-info --insert-ignore mydatabase mytable > data1.sql
(对于data2.sql、data3.sql、data4.sql也是一样,每个服务器一个)
将转储文件复制到要合并数据的服务器。
创建表:
mysql mydestdatabase < create.sql
加载所有数据:
pv -pert data*.sql | mysql mydestdatabase
我喜欢为此使用pv -pert,因为它会显示一个进度条。您可能必须安装pv,因为它在大多数系统上默认不存在。如果您不想这样做,只需使用cat。
【讨论】:
您可以执行四个“插入”命令,或者 UNION 运算符也可以工作。
【讨论】:
MySql 确实有INSERT IGNORE,它允许您从所有表中愉快地一个接一个地插入。 DBMS 将处理(在丢弃的意义上)重复项。
这可能不是最有效的选择,但我认为这将是一次性操作。
【讨论】:
将 4 个表定义为每个表的 ID 都是唯一的主键。 然后只需对所有 4 个表进行外部联接。
【讨论】: