最核心判断是目标库版本必须≥5.7.8且实测支持json类型,否则建表失败;导出需显式指定utf8mb4字符集,导入须确保字段为json类型及字符集正确,禁用load data infile,坚持mysqldump+mysql命令导入并验证json_valid()。

跨版本迁移 JSON 字段,最核心的判断是:目标库版本必须 ≥ 5.7.8,否则直接建表失败,不是数据导不出,是结构都建不起来。
确认目标库是否真正支持 JSON 类型
别只看版本号,要实测。MySQL 5.7.0 到 5.7.7 虽然带 JSON 关键字,但功能不完整;只有 ≥ 5.7.8 才是 GA 稳定版。
- 在目标库执行
SELECT JSON_TYPE('{"a":1}');—— 返回OBJECT才算通过;返回NULL或报错说明不支持 -
SHOW DATA TYPES LIKE 'json';必须有结果;没有则说明该版本未启用 JSON 支持(比如编译时禁用了) - 如果目标库是 MySQL 5.6 或更低,
JSON类型只能退化为TEXT,且后续无法用->、JSON_EXTRACT()等函数,应用层必须改逻辑
mysqldump 导出时字符集与连接参数必须显式指定
JSON 值本身是 UTF-8 编码,但 mysqldump 默认可能用 latin1 连接,导致中文或 emoji 在导出文件里变成问号;更隐蔽的是字段定义若没显式设 CHARACTER SET utf8mb4,四字节字符会被自动截断。
- 导出命令必须加
--default-character-set=utf8mb4: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 dump.sql;否则即使导出正常,导入后也可能乱码或丢数据
跨 5.7 → 8.0 迁移时排序规则和用户表结构要手动降级
MySQL 8.0 默认排序规则是 utf8mb4_0900_ai_ci,5.7 客户端或低版本工具连接时会报 unknown collation;同时 mysql.user 表结构变化(password 字段被移除),权限脚本执行会中断。
- 导出 SQL 中所有
COLLATE utf8mb4_0900_ai_ci必须替换为COLLATE utf8mb4_unicode_ci(5.7 支持的最高兼容排序规则) -
CREATE USER和GRANT语句里的IDENTIFIED WITH caching_sha2_password要改为IDENTIFIED WITH mysql_native_password,否则 5.7 客户端无法解析 - 权限脚本中涉及
mysql.user表的查询(如SELECT password FROM mysql.user)必须删掉或改用authentication_string字段
避免用 LOAD DATA INFILE 导入 JSON 字段
LOAD DATA INFILE 不理解 JSON 类型,它只按分隔符切文本,把整段 JSON 当普通字符串塞进去。一旦源 JSON 含换行、制表符或未转义引号,导入后 JSON_VALID() 直接返回 0,所有 JSON 函数失效。
- 坚持用
mysqldump+mysql命令导入,这是唯一能触发 MySQL 内部 JSON 校验和自动解析的路径 - 导入后立即验证:
SELECT id, JSON_VALID(json_col), JSON_LENGTH(json_col) FROM table LIMIT 10;—— 对比源库结果,确保值不为空、长度一致、校验通过 - 若发现部分 JSON 字段为
NULL或长度异常,大概率是导出时字符集没对齐,或目标表字段类型没设成JSON(比如误建为TEXT)
最容易被忽略的点是:JSON 字段的字符集必须绑定到列级,不能只靠表级默认值;而 mysqldump 不会自动补全列级 CHARACTER SET utf8mb4,得人工核对 SHOW CREATE TABLE 输出并补上。










