最稳导结构方式:MySQL用mysqldump -d dbname,PostgreSQL用pg_dump -s并加--no-owner --no-privileges,SQL Server推荐SqlPackage.exe;需注意外键顺序、字符集兼容性及隐式依赖。
mysqldump -d 只导结构不导数据最稳
直接用 mysqldump -d 是最可靠的方式,它明确跳过数据行,只生成 create table、create index 等 ddl 语句。很多人误加 --no-data 却漏掉数据库名,结果输出为空——-d 是 --no-data 的简写,但必须跟上目标库名,否则命令静默失败。
-
mysqldump -u root -p -d mydb > schema.sql—— 正确,-d和库名紧挨着 - 不加
-d或写成mysqldump -u root -p mydb --no-data=1(错误参数值)会导出全量数据 - 如果库含视图或存储过程,需额外加
--skip-triggers --no-create-info等控制,否则可能混入INSERT或触发器定义
pg_dump -s 导出 PostgreSQL 结构的等效方案
PostgreSQL 没有 -d 这种缩写,必须用 -s(schema-only),且默认包含权限和注释,容易在迁移时因用户不存在报错。若只要干净建表语句,得组合过滤参数。
-
pg_dump -U postgres -s mydb > schema.sql—— 基础可用,但含GRANT和COMMENT - 加
--no-owner --no-privileges可去掉所有权和权限语句,避免目标环境用户缺失问题 - 若表依赖
EXTENSION(如uuid-ossp),-s不自动导出 extension 创建语句,需手动补CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
导出结构时忽略外键约束的坑
导出的 SQL 若直接执行,可能因外键顺序错乱失败:比如先建子表再建父表,而子表 FOREIGN KEY 引用尚未存在的表。MySQL 默认导出含 SET FOREIGN_KEY_CHECKS=0,但 PostgreSQL 不自动处理。
- MySQL 下
mysqldump -d默认已包裹SET FOREIGN_KEY_CHECKS=0,无需额外操作 - PostgreSQL 的
pg_dump -s不禁用检查,需在导入前手动加SET CONSTRAINTS ALL DEFERRED;或调整建表顺序 - 更稳妥的是导出后 grep 删除所有
FOREIGN KEY行,等所有表建完再单独执行ALTER TABLE ... ADD CONSTRAINT
SQL Server 用 sqlcmd + sys.tables 精准提取
SSMS 的“生成脚本”功能常带 GUI 依赖和冗余设置,命令行更可控。核心是查 sys.tables 过滤用户表,再用 sp_help 或 sys.columns 拼结构——但实际推荐用 sqlcmd 调 sp_executesql 执行动态 SQL 生成。
-
sqlcmd -S localhost -d mydb -E -Q "SELECT 'CREATE TABLE ['+t.name+'] (' FROM sys.tables t WHERE t.type = 'U'" -o schema.sql—— 仅开头,需完整拼接列定义 - 真正实用的是用微软官方工具
SqlPackage.exe:SqlPackage.exe /Action:Extract /SourceDatabaseName:mydb /TargetFile:schema.dacpac,再用/Action:Script导出纯 DDL - 注意
IDENTITY列和COMPUTED列在脚本中需显式保留属性,否则重建后行为异常
跨数据库导结构最难的不是命令本身,而是隐式依赖:排序规则、字符集、自定义类型、函数依赖。哪怕只导 CREATE TABLE,utf8mb4_0900_as_cs 这种 MySQL 8.0 默认 collation 在老版本里根本无法执行。别只盯着“有没有数据”,先看“这些语句在哪能跑通”。

















