选“结构和数据”需手动勾选copy data,否则仅复制结构;外键、自增、字符集、json、虚拟列等细节易丢失,推荐用show create table+insert select或mysqldump精准控制。
navicat 里复制表结构和数据,选“结构和数据”还是“仅结构”?
直接看右键菜单里的 copy table 功能——它默认只复制结构,不带数据。想连数据一起搬,必须手动勾选 copy data 选项,否则执行完发现新表空空如也,是新手最常踩的坑。
常见错误现象:Table 'xxx' doesn't exist 看似是目标库没建好,其实是复制中途断了或没选数据导致后续依赖失败;更隐蔽的是字段长度、注释、自增起始值这些细节被忽略,结果插入时报 Data too long 或主键冲突。
- 使用场景:跨库迁移、测试环境初始化、紧急备份后快速重建
- 注意
Auto Increment值不会自动继承,新表从 1 开始,得进Table Properties → Options手动改Auto increment - 如果源表有外键,Navicat 默认不复制约束,得在
Advanced Options里勾上Foreign keys,否则关联逻辑就断了
用 Navicat 执行 SQL 复制时,CREATE TABLE ... LIKE 和 INSERT INTO ... SELECT 怎么配才不丢东西?
图形界面点几下看似省事,但复杂表(含分区、全文索引、生成列)容易漏项。这时候得切到 Query 标签页手写 SQL,控制力更强。
关键不是语句本身,而是顺序和上下文:
- 先用
SHOW CREATE TABLE `source_table`拿完整建表语句,复制出来,把表名替换成新名,再执行——这能保住字符集、排序规则、注释、分区定义 - 再跑
INSERT INTO `new_table` SELECT * FROM `source_table`,但注意:如果字段顺序不一致或有计算列,会报Column count doesn't match,得显式写出字段列表 - 大表务必加
SET SQL_LOG_BIN = 0;(仅限从库或非生产环境),不然 binlog 写爆磁盘;同时关掉autocommit,用事务包住整个插入,避免中途失败留脏数据
Navicat 导出为 SQL 文件再导入,为什么中文变问号或字段乱序?
根本原因不在 Navicat,而在导出时没锁死字符集。默认导出用的是连接当前的 character_set_client,如果建库时设的是 utf8mb4,而导出时连接用的是 latin1,那所有中文字段定义就全歪了。
实操要点:
- 导出前,在 Navicat 连接属性里确认
Character set设为utf8mb4,不是UTF-8(后者是 Navicat 的显示别名,底层可能映射错) - 导出 SQL 文件时,勾选
Include DROP TABLE / CREATE TABLE,但**不要**勾Include INSERT statements——数据量大时单独导出更稳 - 导入前,先在目标库执行
SET NAMES utf8mb4;,再运行 SQL 文件,否则CREATE TABLE语句里的CHARACTER SET子句可能被忽略
复制含 JSON 字段或虚拟列的表,Navicat 8.0+ 和老版本行为差异在哪?
Navicat 7.x 对 JSON 类型识别成 LONGTEXT,导出 SQL 时不带 JSON_VALID() 检查,复制过去的数据看着正常,但用 -> 操作符查就会报错 Invalid JSON text。8.0+ 版本修复了这点,但前提是源库 MySQL 版本 ≥ 5.7.8,且 Navicat 连接协议要设为 MySQL 5.7+。
虚拟列(GENERATED ALWAYS AS)更麻烦:Navicat 默认不导出生成逻辑,只当普通字段处理。结果新表里该列变成 NULL 或报错 Field doesn't have a default value。
- 检查方法:导出 SQL 后搜
AS (,看有没有保留生成表达式 - 临时绕过:导出前在源表加个同名普通列,用触发器同步值,复制完再删触发器(仅限小数据量)
- 真正可靠的做法:不用 Navicat 图形操作,直接用
mysqldump --no-create-info --skip-triggers配合--set-gtid-purged=OFF导数据,结构另用SHOW CREATE TABLE补
复制表这事,越想一步到位越容易漏细节。字符集、自增值、外键、虚拟列、JSON 类型——每个都可能在某个环节静默失效。盯着 Navicat 界面点不如打开 SQL 日志看它到底发了什么命令。











