MySQL用CREATE TABLE ... LIKE最轻量复制结构,继承索引、AUTO_INCREMENT等但不复制外键;PG需显式INCLUDING ALL;Oracle用DBMS_METADATA.GET_DDL并需过滤参数;mysqldump --no-data是跨环境兜底方案。
MySQL 中用 CREATE TABLE ... LIKE 复制表结构最轻量
只复制结构不带数据,是物理设计初期最常用的操作。用 create table new_table like old_table 是最快路径,它连 auto_increment、索引、comment 都原样继承,比 show create table + 手动改名靠谱得多。
常见错误现象:CREATE TABLE new_table AS SELECT * FROM old_table 看似能用,但实际只复制列定义和数据,丢掉索引、主键、默认值、约束——这不是“复制结构”,是“偷懒造了个空壳”。
- 如果源表有
ENGINE=InnoDB,目标表自动继承;但若源表是MyISAM,而当前 MySQL 默认引擎已切为InnoDB,目标表可能意外变成InnoDB(取决于sql_mode和版本) -
LIKE不复制外键定义,哪怕源表有FOREIGN KEY,新表里也完全没影儿 - 分区表、全文索引、生成列(
GENERATED COLUMN)在 5.7+ 支持,但 5.6 及更早版本会静默忽略
PostgreSQL 里得靠 CREATE TABLE ... (LIKE ...) 加括号参数控制细节
PG 没有 MySQL 那种无脑 LIKE,必须显式写括号,并选填参数,否则连基本约束都不带。最常用的是:CREATE TABLE new_table (LIKE old_table INCLUDING ALL)。
使用场景:建测试表、分表模板、灰度环境同步结构。漏掉 INCLUDING 后缀就等于白写——默认只复制列名和类型,其余全丢。
-
INCLUDING ALL包含索引、约束、默认值、存储参数、注释,但不包括继承关系和行级安全策略(RLS) - 想排除某个东西?比如不要索引,就写
INCLUDING ALL EXCLUDING INDEXES - 如果源表用了
IDENTITY列(PG 10+),INCLUDING ALL会复制,但新表的序列不会自动关联,得手动ALTER SEQUENCE ... OWNED BY
跨库或跨实例复制时,mysqldump --no-data 是最稳的兜底方案
当不能直连目标库(比如权限受限、网络隔离),或者要批量导出几十张表时,mysqldump --no-data 比手写 SQL 或反复执行 LIKE 更可靠。
性能影响小,因为不读数据页;但要注意字符集和 SQL 模式兼容性——导出语句里可能含 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci,目标 MySQL 5.7 跑不了 _0900_ai_ci,得提前替换。
- 命令示例:
mysqldump -h src_host -u user db_name table1 table2 --no-data --skip-triggers --skip-routines > schema.sql -
--skip-triggers和--skip-routines必加,否则可能混入业务逻辑,破坏“纯结构”意图 - 导出后别直接
mysql ,先检查是否有CREATE DATABASE或USE语句——它们可能把表建到错库
Oracle 用 DBMS_METADATA.GET_DDL 提取 DDL,但默认带存储参数和统计信息
Oracle 没有类似 LIKE 的语法,DBMS_METADATA.GET_DDL('TABLE', 'T1') 是标准做法,但它返回的 DDL 常含 STORAGE、PCTFREE、甚至 STATISTICS,这些在新环境往往不合适。
容易踩的坑:直接执行返回结果,可能因表空间不存在、用户权限不足或参数不兼容报错,比如 ORA-00959: tablespace 'USERS' does not exist。
- 执行前先设过滤:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false) - 去掉统计信息:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS_AS_ALTER',false)(避免拆成多条ALTER) - 最终记得重置:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'DEFAULT'),否则影响后续调用
物理设计阶段最耗时间的不是写 SQL,而是反复验证“这个结构到底有没有被完整复制”。索引漏了、默认值丢了、字符集不一致——这些问题不会立刻报错,但会在后续插入或查询时突然冒出来。动手前,先确认目标环境的版本、默认配置、权限边界,比多敲十行命令更重要。










