MySQL JSON

MySQL 5.7 新增了一个 JSON 类型,它的设计目标不是简单地把 JSON 当作 TEXT 存储,而是采用内部二进制格式保存 JSON 文档,从而支持结构化访问、校验和部分索引能力。
PS: 8.0 增加了 JSON_TABLE()JSON_VALUE()JSON_OVERLAPS()MEMBER OF()、JSON Schema 验证等能力,同时 JSON 索引和查询能力也进一步增强。

CREATE TABLE users (
    id BIGINT PRIMARY KEY,
    profile JSON
);

写入时 MySQL 会验证数据是否为合法 JSON,因此,JSON 列相比 TEXT 的一个重要优势是数据库层面保证数据格式合法

查询

查询指定 JSON 字段:

SELECT JSON_EXTRACT(profile, '$.name') FROM users;

同时支持 ->->> 操作符:

SELECT profile->'$.name';
SELECT profile->>'$.name';

其中 -> 返回 JSON 值,->> 返回去除 JSON 引号后的字符串。

修改

函数 作用
JSON_SET() 存在则修改,不存在则新增
JSON_INSERT() 只新增,不覆盖已有值
JSON_REPLACE() 只修改已有值
JSON_REMOVE() 删除指定路径
JSON_ARRAY_APPEND() 向数组追加元素
JSON_ARRAY_INSERT() 向数组指定位置插入元素

例如:

UPDATE users
SET profile = JSON_SET(profile, '$.age', 37)
WHERE id = 1;

索引

MySQL 5.7 支持 JSON_CONTAINS()JSON_CONTAINS_PATH()JSON_SEARCH() 等查询函数。

不支持直接给 JSON 列建立普通 B-Tree 索引。常见做法是通过生成列提取需要查询的字段,再对生成列建立索引:

ALTER TABLE users
ADD COLUMN name VARCHAR(100) GENERATED ALWAYS AS (profile->>'$.name'),
ADD INDEX idx_name (name);

这也是 MySQL 5.7 JSON 应用中非常重要的性能实践。

参考资料与拓展阅读

如果你有魔法,你可以看到一个评论框~