MySQL 5.7+ 迁移含 JSON 字段的表需确保目标库版本 ≥ 5.7.8,低版本不支持 JSON 类型;导出时须指定 utf8mb4 字符集并验证字段编码;LOAD DATA INFILE 易导致 JSON 解析失败,建议用 INSERT 或应用层写入;跨库迁移需手动处理 JSON 查询逻辑与业务约束。

MySQL 5.7+ 迁移含 JSON 字段的表,低版本直接报错
MySQL 5.6 及更早版本根本不识别 JSON 类型,建表语句里一出现 JSON 就会报 ERROR 1064 (42000)。不是数据导不出,是结构都建不起来。迁移前必须确认目标库版本 ≥ 5.7.8(JSON 类型正式 GA 的起点)。
实操建议:
- 查源库版本:
SELECT VERSION(); - 查目标库是否支持:
SELECT @@version; SELECT JSON_TYPE('{"a":1}');—— 如果返回NULL或报错,说明不支持 - 若目标库是 5.6 或更低,
JSON字段只能退化为TEXT,且后续无法用->、JSON_EXTRACT()等函数查询
mysqldump 导出时 JSON 字段内容被截断或乱码
本质是字符集和客户端连接参数没对齐。虽然 JSON 值本身是 UTF-8 编码,但 mysqldump 默认可能用 latin1 连接,导致中文 JSON 值在导出文件里变成问号或乱码;更隐蔽的是,如果字段定义没显式指定 CHARACTER SET utf8mb4,超长 emoji 或四字节 UTF-8 字符会被 MySQL 自动截断(即使导出看着正常,导入后也丢数据)。
实操建议:
- 导出时强制指定连接字符集:
mysqldump --default-character-set=utf8mb4 -u user -p db table > dump.sql - 检查原表字段定义:
SHOW CREATE TABLE table;—— 确认JSON字段所在列的CHARSET是utf8mb4,不是utf8(MySQL 的utf8实为utf8mb3) - 导入前,在目标库执行:
SET NAMES utf8mb4;,再 source 文件
使用 LOAD DATA INFILE 导入 JSON 字段,字段值被当成字符串解析失败
LOAD DATA INFILE 不理解 JSON 类型,它只按字段分隔符切分文本,把整段 JSON 当作普通字符串塞进列里。如果源文件里 JSON 值含换行、制表符或引号,又没正确转义,导入后 JSON_VALID() 直接返回 0,后续所有 JSON 函数都失效。
实操建议:
- 确保源 CSV/TSV 中 JSON 字段内容被双引号包裹,且内部双引号已转义为
\"(例如:"{\"name\":\"张三\",\"tags\":[\"前端\"]}") - 导入后立刻验证:
SELECT id, JSON_VALID(json_col), LENGTH(json_col) FROM table LIMIT 5;——JSON_VALID()为 0 的行必须人工排查 - 避免用
LOAD DATA INFILE处理复杂 JSON;优先选INSERT ... VALUES或应用层批量写入,由 MySQL 服务端做语法校验
从 MySQL 迁出到其他数据库(如 PostgreSQL、MongoDB),JSON 字段结构丢失
MySQL 的 JSON 类型只是存储格式,不强制 schema;而 PostgreSQL 的 JSONB 虽兼容,但默认不会自动转换 MySQL 的 JSON 函数逻辑(比如 col->"$.name" 在 PG 里得写成 col->>'name');MongoDB 更是直接把整条记录当文档存,原 JSON 字段会变成嵌套对象,但 MySQL 里用 JSON_CONTAINS() 做的查询逻辑完全无法平移。
实操建议:
- 不要依赖“自动类型映射”——导出时把
JSON字段用JSON_UNQUOTE(JSON_EXTRACT(col, '$'))拉成纯字符串,再由目标库按需解析 - 若迁往 PostgreSQL,建表时用
JSONB,但导入后需重写所有 JSON 查询语句,->和->>行为不等价 - 跨引擎迁移时,
JSON字段的业务含义比技术类型更重要:先厘清哪些字段真需要 JSON 查询能力,哪些只是存个配置字符串,后者可直接转TEXT
真正麻烦的从来不是导出或导入动作本身,而是 JSON 字段在原系统里承担了哪些隐式契约:比如某个字段约定必须含 status 键,或者数组长度不能超过 5 —— 这些约束不会随数据迁移,却会在新环境里悄悄失效。


















