我需要删除大约 20k 表。我知道不要删除的表的名称。
如果我有表名“a,b,c,d,e,f,g...”,如何删除不在列表“a,b,c”中的所有表?
你可以用这个得到一个列表
SELECT CONCAT("DROP TABLE ", table_name, ";")
FROM information_schema.TABLES
WHERE table_schema = <whatever your db name is>
AND table_name NOT IN (<your list>);
然后复制粘贴!
我建议你采取以下方法
SHOW TABLES
(或来自information_schema.TABLES
)DROP TABLE
命令现在您有了一个可以针对数据库运行的 SQL 脚本
如果您是 linux shell 忍者,可能想要使用命令行工具,如uniq
,xargs
等来操作文件。使用电子表格可能是另一种处理方式。
试试这个以获得 SQL DROP 语句的结果集:
SELECT CONCAT('DROP TABLE ', TABLE_NAME , ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='YourDatabase'
AND TABLE_NAME NOT IN ('Table1', 'Table2');
复制并粘贴结果,您将获得 20,000 -n条DROP 语句。
您需要从 information_schema.tables 运行 select 并创建一个游标,该游标将遍历结果并执行适当的删除(使用 if 语句)。这是因为 drop 语句不支持选择/过滤或其他选项。(除非在过去的两三年内发生了一些变化)
当您执行 select 语句时,您可以使用以下内容:
WHERE table_name NOT IN ('ssss','dddd');
另一件事是:为什么你的数据库中有 20k 表????
如果您可以摆脱想要在短时间内保持不可用的表格,我将建议一种完全不同的方法。
DROP DATABASE
包含所有表的数据库我今天遇到了同样的问题。这是跳过表 ABC、DEF 和 XYZ 的一种方法:
mysql -Nu USER --password=PASSWORD DATABASE -e 'show tables' | \
perl -ne 'BEGIN { print "SET FOREIGN_KEY_CHECKS=0;\n" };
!/^(ABC|DEF|XYZ)$/ && s/^(.*)/DROP TABLE `\1`;/ && print' | \
mysql -u USER --password=PASSWORD DATABASE
那到底是什么鬼?
有一个更简单的方法。在一行中,在您的命令行类型中:
mysql -u root -p[password] --skip-column-names [database] -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='[database]' AND TABLE_NAME NOT IN ('[table 1]', '[table 2]',..'[table n]');" | cut -f1 | sed -r 's/(.*)/DROP TABLE IF EXISTS \1;/' | mysql -u root -p[password] [database]
您可能会收到两条关于在命令中包含密码的警告。如果这可能是一个问题,您可以清除命令历史记录以“删除证据”:-)
history -c