navicat 同步 enum 时需手动处理类型兼容性:mysql→sqlite 应添加 check 约束;mysql 间同步须校验 enum 值顺序一致;旧版 navicat 需预处理特殊字符并升级;显示为数字是驱动参数问题,应配置 enumasnumeric=false。

Navicat 同步 ENUM 到不支持 ENUM 的数据库(如 MySQL → SQLite)
SQLite 根本没有 ENUM 类型,Navicat 默认会把它转成 TEXT,但不会加 CHECK 约束——结果字段能存任意字符串,失去业务语义和校验能力。更糟的是,如果源库 ENUM 值含单引号、逗号或空格,直接塞进 TEXT 可能导致后续 SQL 执行失败。
实操建议:
- 同步前在源库执行
SHOW COLUMNS FROM table_name LIKE 'status',确认 ENUM 允许的值列表,例如ENUM('active','inactive','pending') - 目标库手动建兼容字段:
ALTER TABLE table_name ADD COLUMN status TEXT CHECK(status IN ('active','inactive','pending')) - 在 Navicat 字段映射步骤中,对这一列取消自动识别(禁用
Auto-detect data types),手动下拉选择TEXT,并确保勾选“Apply to all rows”避免漏项 - 若目标库是 PostgreSQL,别选
TEXT,应选ENUM并提前用CREATE TYPE status_type AS ENUM ('active', 'inactive', 'pending')建好类型,否则同步会报错
MySQL 间同步 ENUM 值顺序不一致导致数据错位
MySQL 的 ENUM 是按定义顺序存储的整数(1-based),不是按字符串值比对。如果源表定义是 ENUM('yes','no'),目标表是 ENUM('no','yes'),哪怕字段名和值都一样,Navicat 同步时会把源的 'yes'(内部值 1)写成目标的第 1 个值 'no',数据就全乱了。
实操建议:
- 不要只看字段名和默认值,必须对比两边的
COLUMN_TYPE完整定义:运行SELECT COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'xxx' AND COLUMN_NAME = 'status' - 若发现顺序不一致,优先统一源/目标定义——改目标表(用
MODIFY COLUMN status ENUM('yes','no')),而非依赖 Navicat 映射 - 若无法改结构,同步时在 Navicat 的“SQL 预处理”里为该列加显式转换:
CASE status WHEN 'yes' THEN 'yes' WHEN 'no' THEN 'no' ELSE status END,绕过底层整数映射 - 禁用 Navicat 的 “Compare data by column values”(在 Options → Data Comparison 中),改用主键 + 显式字段比对,避免因 ENUM 内部序号差异触发误判
Navicat 导出/同步时跳过 ENUM 字段或静默截断
旧版 Navicat(≤15.0.28)对含特殊字符的 ENUM 值(如 ENUM('a,b','c''d'))解析失败,可能直接跳过整列,或把值截断成 'a,且日志里不报错,只在目标表看到空值或乱码。
实操建议:
- 导出前先用 SQL 检查是否有高危 ENUM 值:
SELECT DISTINCT status FROM table_name WHERE status REGEXP '[,']' - 若存在,预处理源数据:新建临时表,用
REPLACE(status, ''', '\'')转义,再同步临时表 - 升级 Navicat 至 16.1+,该版本修复了 ENUM 值中单引号和逗号的解析逻辑
- 关键业务表绝不依赖 Navicat 自动生成 DDL——用
mysqldump --no-data --compact db_name导出原始建表语句,人工核对 ENUM 定义后再导入目标库
同步后 ENUM 字段显示为数字而非字符串
这通常不是同步问题,而是 Navicat 连接参数或客户端行为:MySQL 驱动默认开启 enumAsNumeric=true(尤其 JDBC),导致查询结果把 ENUM 当整数返回,Navicat 就直接显示 1/2/3。
实操建议:
- 检查 Navicat 连接属性 → Advanced → 在 Connection String 末尾追加
;enumAsNumeric=false(MySQL)或?stringtype=unspecified(PostgreSQL) - 若用 SSH 隧道或代理,确认中间层没重写连接参数
- 验证方式:在 Navicat 查询窗口执行
SELECT status + 0, status FROM table_name LIMIT 1,若前者是数字、后者是空或乱码,就是驱动配置问题 - 注意:这个显示问题不影响数据本身,但会干扰人工校验——务必在同步前就调通显示,否则你根本看不出同步是否成功
COLUMN_TYPE 和 SHOW CREATE TABLE,比事后追查三天数据错位要省力得多。











