在MySQL数据库管理中,复制表是一项常见操作,可能用于数据备份、测试环境搭建、表结构迁移或数据分析等场景,MySQL提供了多种复制表的方法,每种方法适用于不同的需求场景,如仅复制表结构、复制表结构及数据,或复制表结构并添加索引约束等,以下将详细介绍MySQL复制表的各类命令及其使用场景、操作步骤和注意事项。

复制表结构及数据的基本方法
使用CREATE TABLE ... SELECT
语句
这是最直接的方法,通过一条SQL语句同时完成表结构的复制和数据的迁移,语法结构为:
CREATE TABLE 新表名 AS SELECT * FROM 源表名;
将students
表复制为students_backup
:
CREATE TABLE students_backup AS SELECT * FROM students;
特点:
- 优点:操作简单,一步完成结构和数据复制。
- 缺点:不会复制原表的索引、主键、自增属性和外键约束,仅复制列定义和数据类型。
- 适用场景:快速创建包含数据的备份表,且对索引和约束无要求时。
分步复制:先复制结构再复制数据
如果需要保留原表的索引、约束等高级属性,可以分两步操作:
第一步:使用LIKE
关键字复制表结构(不包含数据):

CREATE TABLE 新表名 LIKE 源表名;
CREATE TABLE students_like LIKE students;
第二步:使用INSERT INTO ... SELECT
语句复制数据:
INSERT INTO 新表名 SELECT * FROM 源表名;
INSERT INTO students_like SELECT * FROM students;
特点:
- 优点:完整保留原表的索引、主键、自增字段和外键约束。
- 缺点:需要执行两条SQL语句,操作稍复杂。
- 适用场景:需要严格复制表结构,包括索引和约束的完整备份。
仅复制表结构的方法
如果只需要表结构而不需要数据,可以使用以下方法:
使用CREATE TABLE ... LIKE
如前所述,该方法仅复制表结构,不包含数据:

CREATE TABLE 新表名 LIKE 源表名;
使用SHOW CREATE TABLE
和手动创建
通过查询原表的建表语句,再执行该语句创建新表:
-- 查询原表建表语句 SHOW CREATE TABLE 源表名; -- 复制结果并修改表名后执行
SHOW CREATE TABLE students
会输出类似以下的语句:
CREATE TABLE `students` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
手动修改表名后执行即可创建结构相同的新表。
特点:
- 优点:灵活性高,可手动调整建表语句。
- 缺点:需要手动操作,不适合自动化场景。
- 适用场景:需要微调表结构或跨数据库迁移时。
高级复制场景
复制部分数据或列
如果只需要复制部分数据或列,可以在SELECT
语句中添加条件:
CREATE TABLE 新表名 AS SELECT 列1, 列2 FROM 源表名 WHERE 条件;
仅复制students
表中年龄大于18的学生数据:
CREATE TABLE students_adult AS SELECT id, name FROM students WHERE age > 18;
复制表并修改数据类型或列名
通过SELECT
语句的别名功能,可以在复制时修改列名或数据类型:
CREATE TABLE 新表名 AS SELECT 列1 AS 新列名, CAST(列2 AS 数据类型) FROM 源表名;
将students
表的name
列改名为student_name
,并将age
列转为unsigned
:
CREATE TABLE students_modified AS SELECT name AS student_name, CAST(age AS UNSIGNED) FROM students;
跨数据库复制表
如果需要在同一MySQL服务器的不同数据库之间复制表,需在表名前添加数据库名前缀:
CREATE TABLE 目标数据库.新表名 AS SELECT * FROM 源数据库.源表名;
从db1
的students
表复制到db2
:
CREATE TABLE db2.students_copy AS SELECT * FROM db1.students;
注意事项
-
自增字段处理:
- 使用
CREATE TABLE ... SELECT
时,新表的自增字段会从1重新开始,不会延续原表的计数。 - 使用
CREATE TABLE ... LIKE
后,需手动设置自增起始值(如ALTER TABLE 新表名 AUTO_INCREMENT = 值
)。
- 使用
-
索引和约束:
CREATE TABLE ... SELECT
不复制索引和约束,若需保留必须使用LIKE
+INSERT
组合。- 外键约束可能因目标表不存在而复制失败,需先确保关联表存在。
-
大数据表性能:
- 复制大表时,建议在低峰期操作,并添加
LOCK TABLES
或分批插入以减少锁表时间。 - 可使用
INSERT INTO ... SELECT ... LIMIT 分页大小
分批复制数据。
- 复制大表时,建议在低峰期操作,并添加
-
存储引擎和字符集:
- 新表的存储引擎和字符集默认与MySQL服务器配置一致,若需与原表一致,需在建表语句中显式指定(如
ENGINE=InnoDB DEFAULT CHARSET=utf8
)。
- 新表的存储引擎和字符集默认与MySQL服务器配置一致,若需与原表一致,需在建表语句中显式指定(如
-
权限问题:
- 执行复制操作需要用户具备
CREATE
、SELECT
和INSERT
权限,以及源表的查询权限。
- 执行复制操作需要用户具备
不同方法的对比
方法 | 是否复制数据 | 是否复制索引/约束 | 语法复杂度 | 适用场景 |
---|---|---|---|---|
CREATE TABLE ... SELECT |
是 | 否 | 低 | 快速数据备份,无需索引 |
CREATE TABLE ... LIKE + INSERT |
是 | 是 | 中 | 完整结构复制,含索引约束 |
SHOW CREATE TABLE 手动创建 |
否 | 是 | 高 | 跨库或需修改结构时 |
部分列/条件复制 | 自定义 | 否 | 中 | 数据筛选或列调整 |
相关问答FAQs
问题1:为什么使用CREATE TABLE ... SELECT
复制表后,新表的自增字段从1开始,而不是延续原表的值?
解答:CREATE TABLE ... SELECT
语句会重置自增计数器,因为它本质上是创建一个新表并插入数据,不会保留原表的AUTO_INCREMENT
计数状态,若需延续自增值,需在复制后手动设置,ALTER TABLE 新表名 AUTO_INCREMENT = (SELECT MAX(id) FROM 源表名) + 1;
,而使用CREATE TABLE ... LIKE
复制结构后,自增计数器默认也会重置,同样需要手动调整。
问题2:如何在复制表时避免锁表对生产环境的影响?
解答:对于大表复制,锁表可能导致业务阻塞,可采取以下措施:
- 使用
INSERT INTO ... SELECT
的分页查询:通过LIMIT
分批插入数据,INSERT INTO 新表名 SELECT * FROM 源表名 WHERE id BETWEEN 1 AND 10000;
,分多次执行。 - 添加
LOW_PRIORITY
或IGNORE
关键字:如INSERT LOW_PRIORITY INTO 新表名 SELECT * FROM 源表名;
,降低语句优先级,减少锁竞争。 - 使用
pt-online-schema-change
工具:Percona Toolkit提供的该工具可在不锁表的情况下修改表结构,也可用于复制表。 - 在低峰期操作:选择业务量较少的时间段执行复制任务。