JSON_VALID 与 JSON_TYPE 是什么
JSON_VALID(x) 判断字符串是否为合法 JSON,返回 1 或 0;JSON_TYPE(x) 返回 JSON 值的类型名(OBJECT、ARRAY、STRING、INTEGER、DOUBLE、BOOLEAN、NULL)。PostgreSQL 的对应物是 jsonb_typeof,返回 object、array、string、number、boolean、null,PG 16 起还支持标准谓词 expr IS JSON。这两个函数主要用于数据体检:导入前校验格式、排查「字段里存了非法 JSON 导致取值全为 NULL」这类问题。
基本信息
| MySQL 校验 | JSON_VALID(str) 返回 1 / 0 |
|---|---|
| MySQL 类型 | JSON_TYPE(json) 返回类型名;输入非法 JSON 会报错 |
| PostgreSQL 类型 | jsonb_typeof(jsonb) 返回 object / array / string / number / boolean / null |
| PostgreSQL 校验 | 16 起支持标准写法 expr IS JSON |
| 类型名差异 | MySQL 区分 INTEGER 与 DOUBLE,PostgreSQL 统一为 number |
典型使用场景
- 导入前校验文本字段是否为合法 JSON
- 排查 JSON 列为空值的行,确认是不是格式非法导致的
- 按类型分支处理:对象与数组走不同逻辑
- 数据质量巡检:找出不符合约定结构的记录
- 迁移前评估类型兼容性,提前发现类型名差异
- 批量导入前先跑一遍校验,把非法记录挑出来单独修复
MySQL 用法
MySQL 用法
SELECT JSON_VALID('{"a":1}') AS ok_obj, # 1
JSON_VALID('{a:1}') AS bad, # 0:键必须带引号
JSON_TYPE('{"a":1}') AS t_obj, # OBJECT
JSON_TYPE('[1,2]') AS t_arr, # ARRAY
JSON_TYPE('123') AS t_int, # INTEGER
JSON_TYPE('12.5') AS t_dbl, # DOUBLE
JSON_TYPE('null') AS t_null; # 字符串 NULL(JSON null)
-- 巡检:找出内容不是对象的行,提前发现结构不一致
SELECT id FROM events
WHERE JSON_VALID(payload) = 1 AND JSON_TYPE(payload) <> 'OBJECT'
LIMIT 20;PostgreSQL 用法
PostgreSQL 用法
-- 按类型分支处理,避免对非数组值直接展开
SELECT id,
jsonb_typeof(payload) AS t,
CASE jsonb_typeof(payload)
WHEN 'object' THEN payload->>'type'
WHEN 'array' THEN jsonb_array_length(payload)::text
ELSE NULL
END AS info
FROM events;
-- PostgreSQL 16 起可直接用标准谓词校验
SELECT '{"a":1}' IS JSON AS ok; -- true
SELECT 'not json' IS JSON AS bad; -- false类型名对照
| JSON 值 | MySQL JSON_TYPE | PostgreSQL jsonb_typeof |
|---|---|---|
| 对象 | OBJECT | object |
| 数组 | ARRAY | array |
| 字符串 | STRING | string |
| 整数 / 小数 | INTEGER / DOUBLE | number |
| 布尔 | BOOLEAN | boolean |
| JSON null | 字符串 NULL | null |
| 结构校验 | JSON_SCHEMA_VALID(8.0.17+) | 无内置 schema 校验,需在应用层实现 |
JSON null 与 SQL NULL 是两回事:JSON_TYPE 对 JSON null 返回字符串 'NULL',而对 SQL NULL 输入返回 SQL NULL;写判空逻辑时两种都要覆盖,否则会漏掉一类数据。
JSON 类型的列在写入时就会校验格式,真正需要 JSON_VALID 的是 TEXT / VARCHAR 列或待导入文件;对 TEXT 列做 JSON 校验属于表达式计算,索引无法使用。
JSON_VALID 只校验语法,不校验业务结构:{"a":1} 是合法 JSON,却可能缺少你需要的键。要做结构约束应使用 JSON_SCHEMA_VALID(MySQL 8.0.17+ 提供),并在应用层做键存在性校验。
校验开销要评估:JSON_VALID 需要把整段文本完整解析一遍,在千万行的大字段列上批量巡检代价不低,建议放进离线任务并分批执行,不要挂在在线接口的查询条件里。