MySQL导入数据库但忽略特定表

MySQL导入数据库但忽略特定表,mysql,mysqldump,mysqlimport,Mysql,Mysqldump,Mysqlimport,我有一个包含一个数据库和大约150个表的大型SQL文件。我希望使用mysqlimport导入该数据库,但是,我希望导入过程忽略或跳过几个表。导入所有表但忽略其中一些表的正确语法是什么?谢谢。mysqlimport不是导入SQL语句的正确工具。此工具用于导入格式化的文本文件,如CSV。您要做的是使用如下命令将sql转储直接提供给mysql客户机: bash > mysql -D your_database < your_sql_dump.sql bash>mysql-D您的\u数据库

我有一个包含一个数据库和大约150个表的大型SQL文件。我希望使用
mysqlimport
导入该数据库,但是,我希望导入过程忽略或跳过几个表。导入所有表但忽略其中一些表的正确语法是什么?谢谢。

mysqlimport不是导入SQL语句的正确工具。此工具用于导入格式化的文本文件,如CSV。您要做的是使用如下命令将sql转储直接提供给
mysql
客户机:

bash > mysql -D your_database < your_sql_dump.sql
bash>mysql-D您的\u数据库
无论是
mysql
还是
mysqlimport
都不能提供您需要的功能。最好的方法是导入整个转储,然后删除不需要的表

如果您可以访问转储文件来自的服务器,那么您可以使用
mysqldump--ignore table=database.table\u you\u dont\u want1--ignore table=database.table\u you\u dont\u want2…
创建一个新的转储文件



如果需要,您可以一次完成一个表格:

mysqldump -p sourceDatabase tableName > tableName.sql
mysql -p -D targetDatabase < tableName.sql
mysqldump-p sourceDatabase tableName>tableName.sql
mysql-p-D targetDatabase
RandomSeed接受的答案可能需要很长时间!根据表的大小,导入表(只是为了稍后删除)可能非常浪费

对于使用创建的文件

mysqldump -u user -ppasswd --opt --routines DBname > DBdump.sql
我目前得到一个大约7GB的文件,其中6GB是一个日志表的数据,我不需要它;重新加载此文件需要几个小时。如果我需要重新加载(出于开发目的,或者如果需要实时恢复),我会浏览文件:

sed '/INSERT INTO `TABLE_TO_SKIP`/d' DBdump.sql > reduced.sql
并重新加载:

mysql -u user -ppasswd DBname < reduced.sql

有一个“gotcha”-注意转储中可能包含“INSERT INTO TABLE_TO_SKIP”的过程。

下面是我的脚本,用于从mysql转储中排除一些表 我使用它来恢复数据库时,需要保留订单和付款数据

从\u dump.sh中排除\u表\u

#!/bin/bash

if [ ! -f "$1" ];
then
    echo "Usage: $0 mysql_dump.sql"
    exit
fi

declare -a TABLES=(
user
order
order_product
order_status
payments
)

CMD="cat $1"
for TBL in "${TABLES[@]}";do
    CMD+="|sed 's/DROP TABLE IF EXISTS \`${TBL}\`/# DROP TABLE IF EXIST \`${TBL}\`/g'"
    CMD+="|sed 's/CREATE TABLE \`${TBL}\`/CREATE TABLE IF NOT EXISTS \`${TBL}\`/g'"
    CMD+="|sed -r '/INSERT INTO \`${TBL}\`/d'"
    CMD+="|sed '/DELIMITER\ \;\;/,/DELIMITER\ \;/d'"
done

eval $CMD
它避免了表的删除和重新创建以及向该表插入数据。
它还剥离了存储在分隔符之间的所有函数和过程;;和分隔符

适用于使用.sql.gz文件的任何人;我发现下面的解决方案非常有用。我们的数据库是25GB以上,我不得不删除日志表

gzip -cd "./mydb.sql.gz" | sed -r '/INSERT INTO `(log_table_1|log_table_2|log_table_3|log_table_4)`/d' | gzip > "./mydb2.sql.gz"
感谢Don的回答和Xosofox的评论以及这篇相关文章:

我不会在生产中使用它,但如果我必须快速导入一些备份,其中包含许多较小的表和一个可能需要数小时才能导入的大怪物表,我很可能会使用“grep-v不需要的表名original.sql>reduced.sql”


然后mysql-f有点旧了,但我想它可能仍然有用

我喜欢@Don's answer(),但觉得必须先写入另一个文件非常烦人…
在我的特殊情况下,这将占用太多的时间和磁盘空间

所以我写了一个小bash脚本:

#!/bin/bash

tables=(table1_to_skip table2_to_skip ... tableN_to_skip)


tableString=$(printf "|%s" "${tables[@]}")
trimmed=${tableString:1}
grepExp="INSERT INTO \`($trimmed)\`"

zcat $1 | grep -vE "$grepExp" | mysql -uroot -p
这不会生成新的sql脚本,而是通过管道将其直接传输到数据库

而且,它确实创建了表,只是没有导入数据(这是我在使用大型日志表时遇到的问题)

除非您在使用
mysqldump--ignore table=database进行转储时忽略了表。不需要的\u table
,否则您必须使用一些脚本或工具过滤掉不想从转储文件导入的数据,然后再将其传递到
mysql
客户端

下面是一个bash/sh函数,该函数将动态(通过管道)从SQL转储中排除不需要的表:

#接受一个参数,即要排除的表列表(不区分大小写)。
#例如,筛选排除“%session%action\u log%\u缓存”
过滤排除(){
不包括当地的;
如果[-n“$1”];则
#修剪并替换/[,;\s]+/为“|”,替换“%”为“[^`]*”
不包括$$(echo“$1”| sed-r的/^[:space:][]*//g;s/[:space:][]*$///g;s/[:space:][g;s/+//g;s/%/[^\`\*/g');
grep-viE“(^INSERT INTO`($EXCLU tns)\`)(^DROP TABLE(如果存在)?\`($EXCLU tns)\`)^LOCK TABLES`($EXCLU tns)\`写入”\
sed的/^CREATE TABLE`/如果不存在,则创建TABLE`/g'
其他的
猫
fi
}
假设您有这样创建的转储:

MYSQL_PWD="my-pass" mysqldump -u user --hex-blob db_name | \
pigz -9 > dump.sql.gz
并希望在导入之前排除一些不需要的表:

pigz -dckq dump.sql.gz | \
filt_exclude '%session% action_log %_cache' | \
MYSQL_PWD="my-pass" mysql -u user db_name

或者,在导入到DB之前,您可以通过管道将其导入文件或任何其他工具。

我不知道这是否可行。您是否可以创建.sql的备份,在文本中查找并删除它们,或者这是您将要一次又一次地做的事情。您可以使用CTRL-H查找并替换为REM stmt,或者在最后运行一点“从表1中删除;“”从表2中删除“那么,有很多地方需要省略吗?如何识别它们?也许考虑导入整个东西,然后在不想保存的表上运行删除表。我认为SQL文件中的一个表可能有问题,所以我的导入过程没有完成。您知道从命令行使用导入过程与从MySQL Workbench使用导入实用程序是否不同吗?谢谢您的评论。我的问题似乎是,当我在MySQL Workbench中使用import命令时,这个过程可以工作,但只导入大约三分之一的表,然后挂起到特定的表上。由于问题表,我无法导入所有表。请尝试直接从命令行导入转储。你也有同样的问题吗?至少你可以看到一些错误信息。这是天才,1小时到30秒。哇!!!太棒了,我刚刚将备份容量从1GB减少到72MB,节省了我很多时间,感谢您考虑了
sed-r
选项和一个RegExp,以防您想一次删除更多的表,比如:
sed-r'/INSERT-INTO`(TABLE1-to-u-SKIP | TABLE2-to-u-SKIP)`/d-DBdump.sql>reduced.sql
只需飞行:
TABLE-to-u-SKIP
就是这样的例子-
pigz -dckq dump.sql.gz | \
filt_exclude '%session% action_log %_cache' | \
MYSQL_PWD="my-pass" mysql -u user db_name