视图比直接写json_extract更可靠,因其将提取、去引号、类型转换逻辑固化封装,避免路径变更多处修改、字符串带引号匹配失败及重复解析开销。

为什么视图比直接写 JSON_EXTRACT 更可靠
因为每次在业务 SQL 里手写 JSON_EXTRACT(payload, '$.user.profile.name'),等于把路径、类型转换、NULL 处理逻辑全暴露在外——结构一变就得改多处,字段值带引号不处理会导致 WHERE name = 'Alice' 匹配失败,而且 MySQL 每次调用都重新解析整段 JSON,CPU 开销线性增长。
CREATE VIEW 中必须包含的三步封装
视图定义里要把“提取 → 去引号 → 类型转换”固化下来,对外只暴露干净列名:
- 对字符串字段,必须套
JSON_UNQUOTE(JSON_EXTRACT(...)),否则返回的是"Alice"而不是Alice - 对数字字段,必须用
CAST(... AS UNSIGNED)或CAST(... AS DECIMAL(10,2)),避免后续SUM()或比较出错 - 对可能为空的路径(如
$.user.avatar_url),JSON_EXTRACT本身返回NULL,JSON_UNQUOTE(NULL)仍是NULL,无需额外CASE WHEN - 别用
->>替代函数——它在 MySQL 5.7 不支持嵌套数组访问(如$[0].name),而JSON_EXTRACT全版本兼容
嵌套数组不能靠视图单层解决
视图本身不改变行数,所以像 $.shops[*].products[*].title 这种路径,即使写进 JSON_EXTRACT,返回的也只是 JSON 字符串 ["无线耳机","快充充电宝"],没法直接 GROUP BY 或 JOIN。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 真正摊开数组得用
JSON_TABLE(MySQL 8.0.4+),且必须配合LATERAL JOIN - 路径里不能直接写
[*]通配符,要拆成两层JSON_TABLE:先展开$.shops[*],再对每个shop.products字段再套一层 - 生产环境必须加
WHERE JSON_VALID(payload)过滤非法 JSON,否则JSON_TABLE遇到脏数据直接报错中断 - 字段类型必须声明为
JSON,不是VARCHAR或TEXT;否则隐式转换可能让JSON_TABLE失效
性能关键:别让 JSON_EXTRACT 出现在 WHERE 条件里
像 WHERE JSON_EXTRACT(data, '$.user.id') = '123' 这种写法,每行都会触发一次完整 JSON 解析,无法走索引,大数据量下响应时间飙升。
- 正确做法是用生成列 + 索引:
ALTER TABLE t ADD COLUMN user_id VARCHAR(32) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.user.id'))) STORED - 然后对
user_id创建普通索引:CREATE INDEX idx_user_id ON t(user_id) - 视图可以基于这个生成列构建,业务查询就变成
SELECT * FROM event_parsed WHERE user_id = '123',毫秒级响应 - 注意字符集:导入时若用
LOAD DATA INFILE,必须指定CHARACTER SET utf8mb4,否则中文路径或值可能被截断或解析失败
复杂点在于:视图能封装单值提取,但跨层级数组展开必须跳出视图思维,用 JSON_TABLE + LATERAL 组合;而性能瓶颈往往不出现在写法上,出在没提前建好生成列和索引。










