推荐文档: mysql官网 -- JSON函数
Mysql 从5.7开始引入json数据类型, 相比于blob存储二进制字符、text存储文本类型数据, json存储的数据会验证是否符合json格式。 而且json能存储的最大文本长度与longBlob 和 longText 文本长度相同。
数据类型 | 存储长度 |
TINYBLOB 、 TINYTEXT |
|
BLOB、TEXT |
|
MEDIUMBLOB、MEDIUMTEXT |
|
LONGBLOB 、LONGTEXT、 JSON |
|
mysql中JSON的处理函数:
函数 | 描述 |
---|---|
-> | 评估路径后从 JSON 列返回值;相当于 JSON_EXTRACT()。 |
->> | 在评估路径并取消引用结果后从 JSON 列返回值;相当于 JSON_UNQUOTE(JSON_EXTRACT())。 |
JSON_ARRAY() | 创建 JSON 数组 |
JSON_ARRAY_APPEND() | 将数据附加到 JSON 文档 |
JSON_ARRAY_INSERT() | 插入 JSON 数组 |
JSON_CONTAINS() | JSON 文档是否包含路径中的特定对象 |
JSON_CONTAINS_PATH() | JSON 文档是否包含路径中的任何数据 |
JSON_DEPTH() | JSON 文档的最大深度 |
JSON_EXTRACT() | 从 JSON 文档返回数据 |
JSON_INSERT() | 将数据插入 JSON 文档 |
JSON_KEYS() | 来自 JSON 文档的键数组 |
JSON_LENGTH() | JSON 文档中的元素数 |
JSON_MERGE() | 合并 JSON 文档,保留重复的键。不推荐使用的 JSON_MERGE_PRESERVE() 同义词(已弃用) |
JSON_MERGE_PATCH() | 合并 JSON 文档,替换重复键的值 |
JSON_MERGE_PRESERVE() | 合并 JSON 文档,保留重复键 |
JSON_OBJECT() | 创建 JSON 对象 |
JSON_OVERLAPS() | (8.0.17版本)比较两个 JSON 文档,如果它们有任何共同的键值对或数组元素,则返回 TRUE (1),否则返回 FALSE (0) |
JSON_PRETTY() | 以人类可读的格式打印 JSON 文档 |
JSON_QUOTE() | 引用 JSON 文档 |
JSON_REMOVE() | 从 JSON 文档中删除数据 |
JSON_REPLACE() | 替换 JSON 文档中的值 |
JSON_SCHEMA_VALID() | (8.0.17版本)根据 JSON 模式验证 JSON 文档;如果文档根据模式进行验证,则返回 1,否则返回 0 |
JSON_SCHEMA_VALIDATION_REPORT() | (8.0.17版本)根据 JSON 模式验证 JSON 文档;以 JSON 格式返回关于验证结果的报告,包括成功或失败以及失败的原因 |
JSON_SEARCH() | JSON 文档中的值路径 |
JSON_SET() | 将数据插入 JSON 文档 |
JSON_STORAGE_FREE() | 部分更新后 JSON 列值的二进制表示中释放的空间 |
JSON_STORAGE_SIZE() | 用于存储 JSON 文档的二进制表示的空间 |
JSON_TABLE() | 将 JSON 表达式中的数据作为关系表返回 |
JSON_TYPE() | JSON 值的类型 |
JSON_UNQUOTE() | 取消引用 JSON 值 |
JSON_VALID() | JSON 值是否有效 |
JSON_VALUE() | (8.0.21版本)在提供的路径指向的位置从 JSON 文档中提取值;将此值作为 VARCHAR(512) 或指定类型返回 |
MEMBER OF() | (8.0.17版本)第一个操作数与作为第二个操作数传递的 JSON 数组的任何元素匹配,返回1,否则返回 0 |
常用的函数介绍:
创建表、并插入数据:
CREATE TABLE `zsm_json` (
`json_test` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
INSERT INTO `zsm_json`(`json_test`) VALUES ('[1,2,3,4]');
INSERT INTO `zsm_json`(`json_test`) VALUES ('{\"a\": 1, \"b\": 2, \"c\": [3, 4, 5]}');
实际应用中最常用的是前两个函数, 从json文本中获取制定值
1、 -> 、 ->> 获取json元素
1.1、 基础操作, 获取json元素: jsonColumn -> '$.keyName'
select json_test -> '$.a' from zsm_json
select json_test -> '$."a"' from zsm_json // a带双引号
select json_test -> '$[0]' from zsm_json // 取第一个值
select json_test -> '$[1]' from zsm_json // 取第二个值
result1:
result2:
result3:
result4:
从上面的结果可以得出结论:
- json列既可以存储json对象也可以存储json数组
- 获取json中特定key的值,可以使用 $.keyName , keyName加不加双引号都行
- 如果json列中存储的是JSON数组, 可以使用$[index] 获取特定索引下的值, 而json对象被认为是只有一个元素的数组
1.2、json对象中存在数组元素或数组元素中存在json对象, 获取下层元素
// 获取JSON对象中key为 ‘c’的JSON数组中下标为2的元素
select json_test -> '$.c[2]' from zsm_json;
select json_test -> '$[0].c[2]' from zsm_json;
两个的查询结果都一样:
1.3 ->> 处理特殊字符
先往数据库中插入一条数据
INSERT INTO `zsm_json`(`json_test`) VALUES ('{"mascot": "Our mascot is a dolphin named \\"Sakila\\"."}');
查询:
select json_test -> '$.mascot' from zsm_json;
select json_test ->> '$.mascot' from zsm_json;
result1:
result2:
可以看到使用 -> 查询到的数据, 对于转义字符 \" 并没有进行转义; 而使用 ->> 查询的结果, 转义字符被转成正常的字符。
-> 的使用不限于select, 也可以用于where 、 update等操作中
2、JSON_EXTRACT 获取json数据
json_extract 的功能与 -> 相似,从json文本中获取数据。 他的语法格式:
JSON_EXTRACT(json_doc, path[, path] ...)
他可以一次获取多个value值, 并存放到一个数组中
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');
具体的执行结果,这里就不再展示了。
3、其它搜索json值函数
- JSON_CONTAINS(target, candidate[, path]) : 判断candidate文档中是否包含target文档, 如果制定了path参数,则在 candidate 的 path 路径中寻找 target。 这里path不能使用通配符。
- JSON_CONTAINS_PATH(json_doc, one / all, path[, path] ...) : 判断json文档中是否包含制定路径。
-
'one'
: 如果文档中至少存在一个路径,则为 1,否则为 0。 -
'all'
: 如果文档中存在所有路径,则为 1,否则为 0。
-
-
JSON_KEYS(json_doc[, path]) : 返回json文档中的所有一级key, 如果path指定, 返回指定路径下的一级key
-
JSON_OVERLAPS(json_doc1, json_doc2) : 比较两个 JSON 文档是否具有任何共同的键值对或数组元素。
-
value MEMBER OF(json_array) : json数组中是否包含value值
-
JSON_SEARCH(json_doc, one / all, search_str[, escape_char[, path] ...]) : 返回json文档中给定字符串的路径。
-
'one'
:搜索在第一次匹配后终止并返回一个路径字符串。未定义首先考虑哪个匹配。当我们要匹配的值有多个, 返回第一个匹配到的value的key。 -
'all'
:搜索返回所有匹配的路径字符串,这样就不会包含重复的路径。如果有多个字符串,它们会自动包装为一个数组。数组元素的顺序未定义。 -
// 下面是mysql官方文档给出的示例语句 SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SELECT JSON_SEARCH(@j, 'one', 'abc'); SELECT JSON_SEARCH(@j, 'all', 'abc'); SELECT JSON_SEARCH(@j, 'all', 'ghi');
-
-
JSON_VALUE(json_doc, path) : 从json文档中获取指定路径下的值。完整的语法格式如下:
JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error]) -- RETURNING type 用于制定返回值类型, -- type 取值 : float/double/decimal/signed/unsigned/date/char/json.... 如果不指定, 默认为 varchar(512) -- on_empty 未找到数据时,操作行为: -- NULL ON EMPTY : 默认行为 -- DEFAULT 'value' ON EMPTY : 返回value, 注意类型匹配 -- ERROR ON EMPTY : 抛出错误 -- on_error 发生错误时, 操作行为 -- NULL ON ERROR: 返回null, 默认行为 -- DEFAULT 'value' ON ERROR : 返回value, 注意类型匹配 -- ERROR ON ERROR : 抛出错误
4、修改JSON值得函数
- JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...) : 将值添加到json文档中指定数组的末尾并返回结果。
- JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...) : 在JSON文档的指定位置插入指定值。
- JSON_INSERT(json_doc, path, val[, path, val] ...) : 在json文档的指定路径上插入值,并返回整个json串
- JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...): 合并多个json对象( json对象不是json数组)。 当多个json文档中存在相同的key时, 后面的key值会覆盖前面的json中的key值。
- 如果第一个参数不是json对象, 则会返回第二个参数, 无论第二个参数是否是json文档。
- 如果第二个参数不是json对象, 第一个参数是json对象, 返回第一个json对象
- JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...) : 合并多个json对象, 不同的是它不会将值覆盖。
- 可以合并json数组
- 如果多个json对象中有相同的key, 这里不是覆盖,而是合并多个json对象中的key值
- JSON_REMOVE(json_doc, path[, path] ...) : 删除json文档中的指定值, 返回删除后的json串
- JSON_REPLACE(json_doc, path, val[, path, val] ...) : 替换json文档中的值
- JSON_SET(json_doc, path, val[, path, val] ...) : 设置JSON文档中的值
-
JSON_SET() 替换现有值并添加不存在的值。
-
JSON_INSERT() 插入值而不替换现有值。
-
JSON_REPLACE()仅替换 现有值。
-
5、JSON 属性函数:
- JSON_DEPTH(json_doc) : 返回json最大深度
- JSON_LENGTH(json_doc[, path]) : 返回json文档长度-- json数组长度, JSON对象key个数
- JSON_TYPE(json_val) : 返回
utf8mb4
指示 JSON 值类型的字符串。这可以是对象、数组或标量类型 - JSON_VALID(val) : 返回0 或 1 以指示是否为有效json串
6、JSON其它函数
- JSON_PRETTY(json_val) : 格式化json文档
- JSON_STORAGE_FREE(json_val) : 对于json列, 还有多少存储空间
- JSON_STORAGE_SIZE(json_val) : 存储json文档的字节数