MySQL 8.0 JSON报错主因是字段类型非JSON或路径未引号,需查Type、规范路径如'$."user"."info"."id"',防范NULL/空字符串致JSON_VALID失效,索引优化靠STORED虚拟列,深层嵌套优先用JSON_TABLE。

JSON字段报错先看Type和路径引号
升级后函数报错,八成不是语法写错了,而是字段类型不对或路径写法不合规。MySQL 8.0 对 JSON 校验更严,JSON_EXTRACT、->> 这类操作要求字段必须是 json 类型,且路径中含点号的 key 必须加双引号。
- 查字段类型:
SHOW COLUMNS FROM table_name LIKE 'col_name',确认Type列是json,不是varchar或text - 非 JSON 类型字段上硬用
->>,会直接报错FUNCTION database.JSON_UNQUOTE does not exist - 错误路径:
'$.user.info.id'→ 8.0 拒绝解析;正确写法是'$."user"."info"."id"'或'$.`user`.`info`.`id`' - 动态拼路径时(如 PHP),要用
addcslashes($key, '"')包裹 key,再拼进 SQL 字符串,避免引号冲突
查询为空但数据存在?检查 NULL、空字符串与非法 JSON
常见现象:用 whereJsonContains 或 ->> 查询返回空集,但 SELECT * 看得到值。根本原因是字段值为 NULL、''(空字符串)或字符串 "null" ——这些在 8.0 下全被 JSON_VALID() 判为非法,导致函数静默失败。
- 查非法数据:
SELECT id, json_col FROM table_name WHERE json_col IS NULL OR json_col = '' OR JSON_VALID(json_col) = 0 -
JSON_VALID('null')返回 1(合法),但JSON_VALID("null")(单引号)返回 0;注意引号类型 - 应用层写入前必须兜底:
$data = $input ?: [],再json_encode($data, JSON_UNESCAPED_UNICODE),绝不能让空值直传
性能差不是没建索引,而是没走对索引
只要你在 WHERE 里直接写 details->>'$.price' 或 JSON_EXTRACT(details, '$.price'),MySQL 就不可能走索引——这是设计使然,不是配置或版本问题。优化关键在于“物化路径值”,而非在函数上建索引。
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 最稳方案:加
STORED虚拟列 + 普通索引
例如:ALTER TABLE goods ADD COLUMN price INT AS (details->>'$.price') STORED,再CREATE INDEX idx_price ON goods(price) - 查询必须写成
WHERE price = 2999,写成WHERE details->>'$.price' = 2999就完全不走索引 - 虚拟列定义要显式指定
COLLATE,否则源字段是utf8mb4_bin、生成列默认用utf8mb4_0900_as_cs,比较时触发隐式转换,索引直接失效 - 用
EXPLAIN验证是否真走索引:看type是ref/range,rows显著小于总行数,且Extra不含Using filesort或Using temporary
嵌套深、数组多?别硬套 JSON_EXTRACT,换 JSON_TABLE
处理 {"orders": [{"items": [{"skuid": 1001}]}]} 这类结构时,JSON_EXTRACT(data, '$.orders[0].items[0].skuid') 每次都全量解析整棵树,性能随文档大小线性下降。真正能下推过滤、支持 JOIN 和 ORDER BY 的,只有 JSON_TABLE。
- 必须显式写
ON EMPTY NULL ON ERROR NULL,否则路径不存在或类型不匹配(比如"1001"字符串 vsINT)会导致整行被丢弃,不是填NULL - 嵌套数组要分层展开:
NESTED PATH '$.items[*]'必须嵌在上层COLUMNS内,且子级PATH以当前数组元素为基准(即$指向items[i]) - 超过 3 层嵌套(如
orders → items → options → price)时,NESTED PATH链变长,解析开销回升,建议提前扁平化或拆表
排查时最容易被忽略的是:虚拟列的 COLLATE 是否与查询条件一致、JSON_VALID() 在非 JSON 类型字段上返回值不可靠、以及 JSON_TABLE 漏掉 ON ERROR 导致静默丢行。这些都不是“功能没开”,而是细节没对齐。


















