CREATE TABLE AS 只复制数据不复制主键、索引等结构,仅适用于临时快照或ETL中间表;生产备份应使用mysqldump/pg_dump。

CREATE TABLE AS 会丢主键和索引,别当全量备份用
它只是把查询结果「建个新表」,不复制原表结构元信息。主键、外键、索引、默认值、注释、分区定义全没了,CREATE TABLE AS SELECT * 后你拿到的是个裸数据表。
- 适合场景:临时导出快照、ETL 中间表、测试环境造数据
- 不适合场景:生产表迁移、灾备恢复、结构+数据一致性要求高的备份
- 执行后立刻检查
SHOW CREATE TABLE new_table,确认没主键、没索引——这是最常被忽略的验证步骤
MySQL 和 PostgreSQL 的语法差异很关键
MySQL 不支持 CREATE TABLE AS 直接带约束,PostgreSQL 支持 INCLUDING ALL 但仅限于 CREATE TABLE ... LIKE,不是 AS。别抄错语法。
- MySQL 只能:
CREATE TABLE new_table AS SELECT * FROM old_table(无结构继承) - PostgreSQL 支持:
CREATE TABLE new_table AS SELECT * FROM old_table(同样无约束),但想带默认值/生成列得加WITH DATA;索引必须手动重建 - 两者都不支持在
AS语句里写PRIMARY KEY(id)或INDEX idx_name ON (col)
大表执行前必须加 WHERE 限行或用 LIMIT
没加条件直接 CREATE TABLE AS SELECT *,等于全表扫描+全量写入,锁表时间长、磁盘暴涨、可能触发 OOM 或超时中断。
- 线上库务必先估算行数:
SELECT COUNT(*) FROM table_name - 导出前加时间范围:
CREATE TABLE backup_202405 AS SELECT * FROM orders WHERE created_at >= '2024-05-01' - 测试环境小批量验证:
CREATE TABLE test_copy AS SELECT * FROM huge_table LIMIT 10000 - 注意:MySQL 8.0+ 对
LIMIT在CREATE TABLE AS中支持良好;老版本可能报错,得换INSERT INTO ... SELECT ... LIMIT
真正要备份单表,优先用 mysqldump/pg_dump 而不是 CREATE TABLE AS
CREATE TABLE AS 是“取数据建新表”,而 mysqldump --no-create-info 或 pg_dump -t table_name --inserts 才是面向备份设计的工具——它们保留主键、索引、字符集、时区行为、甚至自增初始值。
- MySQL 单表导出结构+数据:
mysqldump -u user db_name table_name > table_backup.sql - PostgreSQL 单表只导数据(不含建表语句):
pg_dump -t table_name --column-inserts db_name > data_only.sql - 如果非要用
CREATE TABLE AS,至少后续补一句:ALTER TABLE new_table ADD PRIMARY KEY (id),不然连基本查询性能都保不住
事情说清了就结束。


















