msyql-json类型

45 阅读4分钟

1. json类型简介

json类型不是字符串,json类型优势:

自动验证存储在JSON列中的JSON文档 。无效的文档会产生错误。

优化的存储格式。JSON列中存储的JSON文档将 转换为内部格式,以允许快速读取文档元素。当服务器稍后必须读取以该二进制格式存储的JSON值时,则无需从文本表示形式解析该值。二进制格式的结构使服务器能够直接通过键或数组索引查找子对象或嵌套值,而无需读取文档中它们之前或之后的所有值。

作用:需要扩展单个列的功能,存储复杂格式并支持筛选等,用好 JSON 数据类型,那就能打通关系型和非关系型数据的存储之间的界限,为业务提供更好的架构选择。

5.7版本开始,MySQL 支持 RFC7159定义的原生JSON数据类型,MySQL 8.0.13之前,JSON列不能具有非NULL默认值。MySQL 8.0.17及更高版本中,InnoDB 存储引擎支持JSON数组上的多值索引

JSON列与其他二进制类型的列一样,列不能直接建立索引;可以通过虚拟列建索引,多值索引等。

MySQL 8.0中,优化器可以执行JSON列的局部就地更新,而不是删除旧文档并将整个新文档写入该列

一句话,就是开发中使用的正常json格式,没啥好说的。对象{},数组[]

2.json类型操作函数

1. 合并操作

  MySQL 8.0.3(及更高版本)支持两种合并算 JSON_MERGE_PRESERVE():保留重复键的值,

  JSON_MERGE_PATCH(): 丢弃除最后一个值以外的所有值。

```
-- 合并数组
SELECT JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Preserve,
JSON_MERGE_PATCH('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Patch;

前者合并结果:[1, 2, "a", "b", "c", true, false]
后者合并结果:[true, false]

-- 合并对象
SELECT JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,
JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch;
 前者合并结果: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3}   
 后者合并结果: {"a": 4, "b": 2, "c": 5, "d": 3}
```

2. 创建json值函数

    ```
    -- json数组:JSON_ARRAY()
    SELECT JSON_ARRAY(1,  "abc"  , NULL, TRUE, CURTIME());
    +---------------------------------------------        +
    | JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME())         |
    +---------------------------------------------        +
    | [1, "abc", null, true, "11:30:24.000000"]           |
    +---------------------------------------------        +

    -- json对象: JSON_OBJECT()
    SELECT JSON_OBJECT(  'id'  , 87,  'name'  ,  'carrot'  );
    +-----------------------------------------        +
    | JSON_OBJECT('id', 87, 'name', 'carrot')         |
    +-----------------------------------------        +
    | {"id": 87, "name": "carrot"}                    |
    +-----------------------------------------        +

    -- 字符串转json : JSON_QUOTE(string)
    SELECT JSON_QUOTE(  'null'  ), JSON_QUOTE(  '"null"'  );
    +--------------------        +----------------------        +
    | JSON_QUOTE('null')         | JSON_QUOTE('"null"')         |
    +--------------------        +----------------------        +
    | "null"                     | ""null""                   |
    +--------------------        +----------------------        +
    SELECT JSON_QUOTE(  '[1, 2, 3]'  );
    +-------------------------        +
    | JSON_QUOTE('[1, 2, 3]')         |
    +-------------------------        +
    | "[1, 2, 3]"                     |
    +-------------------------        +
    ```

<!---->

3. json聚合函数

```
+------        +-----------        +--------        +
| o_id         | attribute         | value          |
+------        +-----------        +--------        +
|    2         | color             | red            |
|    2         | fabric            | silk           |
|    3         | color             | green          |
|    3         | shape             | square         |
+------        +-----------        +--------        +


JSON_ARRAYAGG(field)[over_clause]: 字段值聚合为一个json数组 [v1,v2,v3]
SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes FROM t3 GROUP BY o_id;
+------        +---------------------        +
| o_id         | attributes                  |
+------        +---------------------        +
|    2         | ["color", "fabric"]         |
|    3         | ["color", "shape"]          |
+------        +---------------------        +


JSON_OBJECTAGG(key,value)[over_clause]: 字段值聚合为一个json对象
SELECT o_id, JSON_OBJECTAGG(attribute, value) FROM t3 GROUP BY o_id

+------        +---------------------------------------        +
| o_id         | JSON_OBJECTAGG(attribute, value)              |
+------        +---------------------------------------        +
|    2         | {"color": "red", "fabric": "silk"}            |
|    3         | {"color": "green", "shape": "square"}         |
+------        +---------------------------------------        +
```

4. json查询函数

```
JSON_CONTAINS(json_doc, val[, path])
查询json文档是否在指定path包含指定的数据,包含则返回1,否则返回0。如果有参数为NULL或path不存在,则返回NULL

JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] …)
查询是否存在指定路径,存在则返回1,否则返回0。如果有参数为NULL,则返回NULL。
one_or_all只能取值"one"或"all",one表示只要有一个存在即可;all表示所有的都存在才行

JSON_EXTRACT(json_doc, path[, path] …)
从json文档里抽取数据。如果有参数有NULL或path不存在,则返回NULL。如果抽取出多个path,则返回的数据封闭在一个json array里
MySQL 5.7.9+里可以用"-> "替代。MySQL 5.7.13+,还可以用"->> "表示去掉抽取结果的"号。

JSON_KEYS(json_doc[, path])
获取json文档在指定路径下的所有键值,返回一个json array。如果有参数为NULL或path不存在,则返回NULL。

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] …])
查询包含指定字符串的paths,并作为一个json array返回。如果有参数为NUL或path不存在,则返回NULL。
one_or_all:"one"表示查询到一个即返回;"all"表示查询所有。
search_str:要查询的字符串。 可以用LIKE里的’%'或‘_’匹配。
path:在指定path下查。
```

5. 修改函数

```
JSON_ARRAY_APPEND(json_doc, path, val[, path, val] …)
在指定path的json array尾部追加val。如果指定path是一个json object,则将其封装成一个json array再追加。如果有参数为NULL,则返回NULL。


JSON_ARRAY_INSERT(json_doc, path, val[, path, val] …)
在path指定的json array元素插入val,原位置及以右的元素顺次右移。如果path指定的数据非json array元素,则略过此val;如果指定的元素下标超过json array的长度,则插入尾部。

JSON_INSERT(json_doc, path, val[, path, val] …)
在指定path下插入数据,如果path已存在,则忽略此val(不存在才插入)

JSON_REPLACE(json_doc, path, val[, path, val] …)
替换指定路径的数据,如果某个路径不存在则略过(存在才替换)。如果有参数为NULL,则返回NULL。

JSON_SET(json_doc, path, val[, path, val] …)
设置指定路径的数据(不管是否存在)。如果有参数为NULL,则返回NULL

JSON_MERGE(json_doc, json_doc[, json_doc] …)
merge多个json文档。规则如下:
如果都是json array,则结果自动merge为一个json array;
如果都是json object,则结果自动merge为一个json object;
如果有多种类型,则将非json array的元素封装成json array再按照规则一进行mege。
```