JSON_EXTRACT()可提取JSON字段值,但要求字段内容合法,否则返回NULL;需用JSON_VALID()校验,路径须规范(如$.key、$[0]),数组访问须指定下标,且不走索引,仅适用于小数据量场景。

直接说结论:用 JSON_EXTRACT() 提取 JSON 字段值是可行的,但必须确认字段类型是 JSON 或至少内容合法,否则会返回 NULL 或报错;路径写错、嵌套层级误判、数组索引越界是最常踩的坑。
如何判断字段是否支持 JSON_EXTRACT()
不是所有存着“看起来像 JSON”的字符串都能用 JSON_EXTRACT() 安全提取——它要求输入是合法 JSON 文本。MySQL 会做隐式校验:
- 如果字段类型是
JSON,插入/更新时已强制校验,JSON_EXTRACT()可直接用 - 如果字段是
VARCHAR或TEXT,内容含非法字符(如单引号、未转义换行、中文引号、尾部逗号)会导致函数返回NULL,且不报错 - 可用
JSON_VALID(data)检查:返回1才真正可解析,例如SELECT data, JSON_VALID(data) FROM tab_json WHERE id = 1;
JSON_EXTRACT() 路径写法常见错误
路径语法看着简单,实际极易写错,尤其对嵌套对象和数组混用的结构:
- 对象属性用
$.key,不是$['key'](后者虽语法合法但易出错,且无法用变量拼接) - 数组元素必须用
$[0]、$[1],不能省略方括号或写成$.0 - 多层嵌套别漏掉中间节点,比如
$.elements.new\old\used\sold\blank中的反斜杠要双写为\\,否则路径解析失败 - 键名含特殊字符(空格、点、反斜杠)必须用引号包裹:
$."my key"或$.elements."new\old"
从 JSON 数组中取值的典型写法
数组不是对象,不能直接 $.name;必须显式指定下标,且注意下标从 0 开始:
- 取第一个对象的
name:JSON_EXTRACT(data, '$[0].name') - 取所有数组元素的
id(返回 JSON 数组):JSON_EXTRACT(data, '$[*].id') - 想展开成多行?得配合
JSON_TABLE()(MySQL 8.0.4+),JSON_EXTRACT()本身不支持横向展开 - 若不确定数组长度,用
JSON_LENGTH(JSON_EXTRACT(data, '$'))先查长度,避免$[999]这类越界访问返回NULL
性能与实际使用边界
JSON_EXTRACT() 是纯计算函数,不走索引——哪怕你在 data 字段上建了函数索引(MySQL 8.0.13+ 支持 JSON_EXTRACT(data, '$.id') 索引),也仅对等值查询有效,范围查询、模糊匹配依然全表扫:
- 小表(
- 高频查询某个 key(如
status、user_id),建议拆出冗余字段并加索引,而不是每次都JSON_EXTRACT() - 用
EXPLAIN FORMAT=TREE看执行计划,如果出现"table": "tab_json", "rows": 123456,说明没走索引,就得警惕了
最麻烦的其实是路径调试——一个嵌套五层的 JSON,少写一个 $ 或错配一对括号,结果就是 NULL,还不好定位。建议先用 SELECT data FROM ... LIMIT 1 拿出原始数据,在线 JSON 格式化工具里人工验证路径,再写进 SQL。


















