MySQL 5.7 中 JSON_EXTRACT 静默返回 NULL 而非报错,路径必须以 $ 开头、数组下标从 0 开始;推荐用 ->> 替代 JSON_UNQUOTE(JSON_EXTRACT()) 获取无引号字符串,并配合 JSON_VALID 过滤非法 JSON,避免 NULL 干扰逻辑。

MySQL 5.7 中能用 JSON_EXTRACT 解析 JSON 字段,但直接写错路径就静默返回 NULL,不是报错——这是最常踩的坑,容易误判数据丢失。
路径必须以 $ 开头,且数组下标从 0 起
路径不合法、字段不存在、JSON 格式错误,JSON_EXTRACT 全部返回 NULL,不会提示哪里错了。所以第一步必须确认路径写法:
-
$.name取顶层字符串字段,不能写成name或$."name"(除非 key 含空格或特殊字符) - 数组元素必须用
$[0],不是$[1];嵌套数组如$[0].items[2].id - key 名含空格、点号、连字符等,得加双引号:
$."user id"、$."cpu.freq" - 想取整个数组第一个对象的
name,写$[0].name,不是$.0.name或$.[0].name
用 ->> 比 JSON_UNQUOTE(JSON_EXTRACT()) 更安全
如果目标值是字符串,JSON_EXTRACT(json_col, '$.name') 返回带双引号的 "tom",程序里容易多一层转义;而 json_col->>'$.name' 直接返回不带引号的 tom(类型为 TEXT):
-
->等价于JSON_EXTRACT(),返回 JSON 类型(仍可链式取值) -
->>等价于JSON_UNQUOTE(JSON_EXTRACT()),返回去引号后的字符串 - WHERE 条件里做字符串匹配,优先用
->>,避免= "tom"匹配失败 - 注意:
->>对非字符串值(如数字、布尔、null)也去引号,但语义不变;对不存在路径仍返回NULL
先用 JSON_VALID 过滤再提取,避免 NULL 干扰逻辑
JSON_EXTRACT 遇到 NULL 字段、非 JSON 字符串(比如纯文本 "abc")、格式错误 JSON,一律返回 NULL。如果你的列是 VARCHAR 类型存的 JSON 字符串,这点尤其关键:
- 加
WHERE JSON_VALID(json_str)再查,能排除脏数据干扰 - 别在 WHERE 里直接写
JSON_EXTRACT(json_str, '$.status') = 'active',它会把非法 JSON 行也纳入计算,结果不可控 - 若字段定义为
JSON类型,插入时已强制校验,JSON_VALID可省略;但生产中很多表仍是VARCHAR存 JSON 字符串 - 性能敏感场景,建议建生成列 + 索引:
ALTER TABLE t ADD COLUMN status TEXT GENERATED ALWAYS AS (data->>'$.status') STORED
JSON_EXTRACT 在 WHERE 中性能差,慎用于大表
JSON_EXTRACT 是逐行计算函数,无法走索引,执行计划里必现 type: ALL(全表扫描):
- 数据量
- 不要在 JOIN 条件或子查询里嵌套多次
JSON_EXTRACT - 高频查询字段(如状态、分类、用户 ID),务必提前提取为普通列并建索引
- MySQL 8.0+ 支持
JSON_TABLE,但 5.7 不支持,别试
真正麻烦的不是语法记不住,而是 NULL 太安静:它既不报错,也不警告,还长得像真数据缺失。上线前一定用 JSON_VALID + IS NOT NULL 组合验证几条典型数据。











