json_extract读取嵌套对象或数组时路径必须以$开头,用.访问对象键、[n]访问数组元素,特殊键名需双引号包裹(如$."user name"),返回值为带引号的json类型,可用json_unquote或->>去除引号。

JSON_EXTRACT 读取嵌套对象或数组时路径怎么写?
JSON_EXTRACT 的第二个参数是 JSON 路径表达式,必须以 $ 开头,路径中用点号(.)访问对象键,用方括号([n])访问数组元素。常见错误是漏掉 $ 或混淆单双引号——路径字符串本身要用单引号包裹,里面不能混用双引号。
- 键名含空格或特殊字符(如
user name)必须用双引号包在路径里:'$. "user name"' - 访问数组第一个元素写成
'$[0]',不是'$.[0]' - 多层嵌套如
{"data": {"items": [{"id": 1}]}},取 id 是'$.data.items[0].id' - 如果路径不存在,
JSON_EXTRACT返回NULL,不是报错
为什么 SELECT JSON_EXTRACT(col, '$.name') 返回带双引号的字符串?
这是正常行为。JSON_EXTRACT 返回的是 JSON 类型值(即带引号的字符串、数字、布尔等原始 JSON 表示),不是普通 SQL 字符串。比如字段存 {"name": "Alice"},JSON_EXTRACT(col, '$.name') 返回的是 "Alice"(含双引号),类型为 JSON。
- 要去掉引号转成普通字符串,得用
JSON_UNQUOTE(JSON_EXTRACT(col, '$.name')),或者直接用更简洁的col->>'$.name'(MySQL 5.7+) -
->等价于JSON_EXTRACT,->>等价于JSON_UNQUOTE(JSON_EXTRACT(...)) - 在 ORDER BY 或 WHERE 中比较字符串时,不加
JSON_UNQUOTE可能导致隐式类型转换异常,尤其和VARCHAR字段对比时
JSON_EXTRACT 在 WHERE 条件里性能很差怎么办?
JSON_EXTRACT 无法使用普通索引,每次都要全表解析 JSON 字段,大数据量下非常慢。
- MySQL 5.7+ 支持生成列(generated column)+ 虚拟列索引:
ALTER TABLE t ADD name_text VARCHAR(100) AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.name'))) STORED;
然后CREATE INDEX idx_name ON t(name_text); - 如果只查是否存在某个键,用
JSON_CONTAINS_PATH(data, 'one', '$.name')比JSON_EXTRACT快,它不解析值,只检查路径结构 - 避免在 WHERE 中对
JSON_EXTRACT结果做函数运算,比如UPPER(JSON_EXTRACT(...)),会彻底阻止任何潜在优化
JSON_EXTRACT 读取布尔或 NULL 值时要注意什么?
JSON 中的 true/false/null 被提取后仍是对应 JSON 类型,但 MySQL 会尝试转换:布尔转为 0/1,null 转为 SQL NULL。问题在于歧义——JSON 里的 "false"(字符串)和 false(布尔)提取结果不同。
- 判断是否为布尔 false,不能只靠
= 0,因为字符串"0"、数字0、布尔false都可能转成 0 - 安全做法是先用
JSON_TYPE(JSON_EXTRACT(col, '$.flag')) = 'BOOLEAN'确认类型,再结合JSON_EXTRACT取值 - 提取
null值时,JSON_EXTRACT返回 JSONnull,和 SQLNULL行为一致,但IS NULL判断有效,= NULL无效
实际用的时候,别只盯着 JSON_EXTRACT 写完就跑,路径写错、类型没处理、WHERE 里乱用——这三个地方出问题的概率远高于语法本身。











