用--no-data最稳导出表结构:它只保留create table等定义,跳过insert;多表用空格分隔,--ignore-table必须带库名前缀,表名含特殊字符需反引号包裹。

只导出表结构不带数据:用 --no-data 最稳
想备份建表语句但不要任何行数据,--no-data 是唯一可靠选项。它会跳过 INSERT 语句,只保留 CREATE TABLE 及相关 COMMENT、ENGINE、字符集等定义。
常见错误是误用 --where="1=0" 或删完数据再导出——前者在某些 MySQL 版本里仍可能生成空 INSERT,后者多一步且易出错。
实操建议:
- 命令格式:
mysqldump -u root -p --no-data database_name table_name > schema.sql - 如果表名含特殊字符(如横线),必须用反引号包裹:
mysqldump -u root -p --no-data db \`my-table\` - 加
--skip-extended-insert可让输出更易读(单行 INSERT 被禁用,但结构导出不受影响)
只导出多个指定表的结构:用空格分隔表名,别用逗号
mysqldump 不支持逗号分隔表名,写成 table1,table2 会被当做一个表名处理,直接报错 Unknown table 'table1,table2'。
正确做法是把多个表名作为独立参数传入,中间用空格隔开。
实操建议:
- 导出两个表结构:
mysqldump -u root -p --no-data mydb users orders > users_orders_schema.sql - 表名含空格或关键字?必须分别加反引号:
mysqldump -u root -p --no-data mydb \`user info\` \`order\` - 表太多打字麻烦?可先用
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ...生成列表,再拼成命令
过滤掉某些表不导出:用 --ignore-table,注意库名前缀不能省
想导出整个库但跳过几个大日志表?--ignore-table 是唯一内置方案。关键点在于:它**必须带数据库名前缀**,格式是 --ignore-table=database_name.table_name,漏掉 database_name. 就完全失效。
常见坑是复制网上示例时没改库名,或者用变量拼接时忘了加点号,结果该跳过的表照常导出,白白浪费时间和空间。
实操建议:
- 跳过一个表:
mysqldump -u root -p mydb --ignore-table=mydb.audit_log > dump.sql - 跳过多个表?重复写多次
--ignore-table:--ignore-table=mydb.tmp1 --ignore-table=mydb.tmp2 - 不支持通配符,
--ignore-table=mydb.tmp_*无效;需逐个列出
导出结构时避免锁表和权限问题:加 --single-transaction 和检查 SELECT 权限
即使只导结构,mysqldump 默认也会对每个表执行 SHOW CREATE TABLE 和 SHOW TABLE STATUS,这在某些存储引擎(如 MyISAM)下会触发表级读锁。InnoDB 表虽可用 --single-transaction 规避,但该参数对纯结构导出非必需——不过加上更稳妥,尤其当库中混有 MyISAM 表时。
另一个隐形问题是权限:用户必须对目标表有 SELECT 权限(MySQL 8.0+ 还需 LOCK TABLES 或 BACKUP_ADMIN 才能用 --single-transaction)。
实操建议:
- InnoDB 库推荐加:
mysqldump -u user -p --no-data --single-transaction mydb t1 t2 - 确认权限是否足够:
SHOW GRANTS FOR CURRENT_USER;,重点看是否有SELECT和LOCK TABLES - 若权限受限又必须导结构,可改用
SELECT TABLE_SCHEMA, CREATE_TABLE FROM INFORMATION_SCHEMA.TABLES手动提取,但丢失索引/外键细节
真正容易被忽略的是 --ignore-table 的库名前缀和反引号包裹规则——少一个点、多一个逗号,命令就静默失效,而你可能直到还原时才发现缺了关键表结构。











