JSON_CONTAINS查询需严格遵循JSON语法:字符串值必须用双引号并外层单引号包裹,数字/布尔值不加引号;指定路径可避免误匹配;性能优化须依赖虚拟列+索引。

直接用 JSON_CONTAINS 就行,但字符串必须加双引号、数字不加,否则永远查不到。
字符串值必须写成 "value",不能写成 'value' 或 value
MySQL 把 candidate 当作完整 JSON 文档解析,所以字符串必须是合法 JSON 字符串 —— 即外层单引号包裹、内层双引号包裹。常见错误写法:'developer'(缺内层双引号)、"developer"(缺外层单引号导致语法错误)。
-
JSON_CONTAINS(tags, '"developer"')✅ 正确 -
JSON_CONTAINS(tags, 'developer')❌ 解析失败,返回NULL -
JSON_CONTAINS(tags, "developer")❌ SQL 语法错误(未闭合字符串) - 中文同理:
JSON_CONTAINS(departments, '"技术部"')✅
查数字或布尔值时,直接传原始值,不加引号
JSON 中的数字、true、false、null 本身就是合法 JSON 值,不需要额外引号包装。加了反而变成字符串,类型不匹配。
-
JSON_CONTAINS(scores, 95)✅ 查数字 95 -
JSON_CONTAINS(flags, true)✅ 查布尔值true -
JSON_CONTAINS(data, '95')❌ 查的是字符串"95",不是数字95 -
JSON_CONTAINS(data, '"true"')❌ 查的是字符串"true",不是布尔值true
限定路径能避免误匹配,尤其当 JSON 结构嵌套时
不指定 path 参数时,JSON_CONTAINS 会递归搜索整个文档,可能命中不该命中的字段。例如 info 字段含 {"name": "admin", "roles": ["user", "admin"]},查 "admin" 会同时匹配 name 和 roles —— 通常你只想要后者。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
JSON_CONTAINS(info, '"admin"')→ 可能误命中name字段 -
JSON_CONTAINS(info, '"admin"', '$.roles')→ 只查roles数组 -
info->'$.roles'必须是数组类型,否则JSON_CONTAINS返回NULL - 路径支持通配符:
'$.tags[*]'可用于扁平化多层嵌套数组(MySQL 8.0+),5.7 不支持,别乱试
性能关键:给 JSON 字段建虚拟列 + 索引才真正快
JSON_CONTAINS 本身无法走索引,全表扫描不可避免。想提速,必须配合生成列和二级索引:
- 先加虚拟列:
ALTER TABLE users ADD COLUMN roles_array JSON AS (info->'$.roles'); - 再建索引:
CREATE INDEX idx_roles ON users (roles_array); - 查询时仍用
JSON_CONTAINS(roles_array, '"admin"'),但执行计划会显示用了索引 - 注意:MySQL 5.7 要求虚拟列必须是
STORED或显式声明为VIRTUAL,且仅支持对 JSON 路径表达式生成列
最常被忽略的一点:即使写了正确的 JSON_CONTAINS,只要没建对应索引,数据量一过万,查询就会明显变慢 —— 函数本身没问题,瓶颈在存储引擎层面。










