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

时间:2013-05-24 12:48:16

标签: mysql mysqldump mysqlimport

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

8 个答案:

答案 0 :(得分:106)

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

这给了我一个完整的数据库,创建了“不需要的”表但是空的。如果你真的根本不想要这些表,只需在加载完成后删除空表。

对于多个表,您可以执行以下操作:

sed '/INSERT INTO `TABLE1_TO_SKIP`/d' DBdump.sql | \
sed '/INSERT INTO `TABLE2_TO_SKIP`/d' | \
sed '/INSERT INTO `TABLE3_TO_SKIP`/d' > reduced.sql

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

答案 1 :(得分:9)

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

bash > mysql -D your_database < your_sql_dump.sql

mysqlmysqlimport都不提供您需要的功能。你最好的机会是导入整个转储,然后丢弃你不想要的表。

如果您有权访问转储来自的服务器,那么您可以使用mysqldump --ignore-table=database.table_you_dont_want1 --ignore-table=database.table_you_dont_want2 ...创建新转储。


scroll down for a better option

答案 2 :(得分:1)

如果需要,您可以一次执行此表:

mysqldump -p sourceDatabase tableName > tableName.sql
mysql -p -D targetDatabase < tableName.sql

答案 3 :(得分:1)

适用于使用.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的评论以及与此相关的文章: Use zcat and sed or awk to edit compressed .gz text file

答案 4 :(得分:0)

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

exclude_tables_from_dump.sh

#!/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

它避免了DROP和reCREATE表并将数据插入到这个表中。 它还删除存储在DELIMITER之间的所有功能和程序;;和DELIMITER;

答案 5 :(得分:0)

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

然后是mysql -f

答案 6 :(得分:0)

有点旧,但认为它仍然可以派上用场...

我喜欢@Don的答案(https://stackoverflow.com/a/26379517/1446005),但感到非常烦恼,您必须先写入另一个文件...
在我的情况下,这会占用太多时间和光盘空间

所以我写了一个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脚本,而是将其直接管道传输到数据库
而且,它确实会创建表,只是不导入数据(这是我使用大型日志表时遇到的问题)

答案 7 :(得分:0)

除非在转储期间使用mysqldump --ignore-table=database.unwanted_table忽略了表,否则必须使用一些脚本或工具来过滤掉不想从转储文件中导入的数据,然后再将其传递到{{1 }}客户。

这是一个bash / sh函数,可以从运行中的SQL转储中(通过管道)排除不需要的表:

mysql

假设您创建了一个转储,如下所示:

# Accepts one argument, the list of tables to exclude (case-insensitive).
# Eg. filt_exclude '%session% action_log %_cache'
filt_exclude() {
    local excl_tns;
    if [ -n "$1" ]; then
        # trim & replace /[,;\s]+/ with '|' & replace '%' with '[^`]*'
        excl_tns=$(echo "$1" | sed -r 's/^[[:space:]]*//g; s/[[:space:]]*$//g; s/[[:space:]]+/|/g; s/[,;]+/|/g; s/%/[^\`]\*/g');

        grep -viE "(^INSERT INTO \`($excl_tns)\`)|(^DROP TABLE (IF EXISTS )?\`($excl_tns)\`)|^LOCK TABLES \`($excl_tns)\` WRITE" | \
        sed 's/^CREATE TABLE `/CREATE TABLE IF NOT EXISTS `/g'        
    else
        cat
    fi
}

并且要在导入之前排除一些不需要的表:

MYSQL_PWD="my-pass" mysqldump -u user --hex-blob db_name | \
pigz -9 > dump.sql.gz

或者您也可以在导入数据库之前通过管道将其导入文件或任何其他工具。