MySQL5.7.8 JSON
Mysql从5.7.8版本开始原生支持JSON(JavaScript Object Notation)类型。确切的是MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生支持JSON格式,该格式不是简单的BLOB类似的替换。
MYSQL JSON官方文档:
11.6 The JSON Data Type
https://dev.mysql.com/doc/refman/5.7/en/json.html
12.17.1 JSON Function Reference
https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html
优点如下:
1、自动验证存储在JSON列中的JSON文档。无效的文档产生错误。
2、优化存储格式。JSON文档存储在JSON列,被转换为内部格式,允许快速读取为文档元素。当以后服务器读取这种二进制格式存储的JSON值时,不需要从文本中分析该值。二进制格式的结构允许服务器直接通过键或数组索引查找子对象或嵌套值,而不必在文档中读取子对象或嵌套值之前或之后的所有值。
JSON函数完整列表#
MySQL官方列出json相关的函数,完整列表如下[doc]:
分类 | 函数 | 描述 |
---|---|---|
创建json | json_array | 创建json数组 |
- | json_object | 创建json对象 |
- | json_quote | 将json转成json字符串类型 |
查询json | json_contains | 判断是否包含某个json值 |
- | json_contains_path | 判断某个路径下是否包json值 |
- | json_extract | 提取json值 |
- | column->path | json_extract的简洁写法,MySQL 5.7.9开始支持 |
- | column->>path | json_unquote(column -> path)的简洁写法 |
- | json_keys | 提取json中的键值为json数组 |
- | json_search | 按给定字符串关键字搜索json,返回匹配的路径 |
修改json | json_append | 废弃,MySQL 5.7.9开始改名为json_array_append |
- | json_array_append | 末尾添加数组元素,如果原有值是数值或json对象,则转成数组后,再添加元素 |
- | json_array_insert | 插入数组元素 |
- | json_insert | 插入值(插入新值,但不替换已经存在的旧值) |
- | json_merge | 合并json数组或对象 |
- | json_remove | 删除json数据 |
- | json_replace | 替换值(只替换已经存在的旧值) |
- | json_set | 设置值(替换旧值,并插入不存在的新值) |
- | json_unquote | 去除json字符串的引号,将值转成string类型 |
返回json属性 | json_depth | 返回json文档的最大深度 |
- | json_length | 返回json文档的长度 |
- | json_type | 返回json值得类型 |
- | json_valid | 判断是否为合法json文档 |
官方文档对全部函数都作了充分解释并提供一定的示例代码。下文挑选了部分函数,演示它们的使用方法。
插入和查询数据#
mysql> CREATE TABLE employees (data JSON);
Query OK, 0 rows affected (0.17 sec)
mysql> INSERT INTO employees VALUES ('{"id": 1, "name": "Jane"}');
Query OK, 1 row affected (0.04 sec)
mysql> INSERT INTO employees VALUES ('{"id": 2, "name": "Joe"}');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM employees WHERE data->'$.id'= 2; -- json路径表达式
+--------------------------+
| data |
+--------------------------+
| {"id": 2, "name": "Joe"} |
+--------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM employees WHERE json_extract(data,'$.id') = 2;
+--------------------------+
| data |
+--------------------------+
| {"id": 2, "name": "Joe"} |
+--------------------------+
1 row in set (0.00 sec)
mysql> SET @j = '["a", "b"]';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT json_extract(@j, '$[0]');
+--------------------------+
| json_extract(@j, '$[0]') |
+--------------------------+
| "a" |
+--------------------------+
1 row in set (0.00 sec)
json路径表达式是json_extract的简洁写法,但存在以下限制[ref]
即,1. 数据源必须是表字段,2. 路径表达式必须为字符串,3. SQL语句中最多只支持一个。
json_contains示例:
mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT json_contains(@j, '{"a": 1}');
+-------------------------------+
| json_contains(@j, '{"a": 1}') |
+-------------------------------+
| 1 |
+-------------------------------+
1 row in set (0.00 sec)
更新数据
json_array_append和json_array_insert示例:
mysql> SET @j = '["a", "b"]';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT json_array_append(@j, '$', 'c');
+---------------------------------+
| json_array_append(@j, '$', 'c') |
+---------------------------------+
| ["a", "b", "c"] |
+---------------------------------+
1 row in set (0.00 sec)
mysql> SET @scalar = '1';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT json_array_append(@scalar, '$', 'c');
+---------------------------------+
| json_array_append(@scalar, '$', 'c') |
+---------------------------------+
| [1, "c"] |
+---------------------------------+
1 row in set (0.00 sec)
mysql> SELECT json_array_insert(@j, '$[1]', 'c');
+------------------------------------+
| json_array_insert(@j, '$[1]', 'c') |
+------------------------------------+
| ["a", "c", "b"] |
+------------------------------------+
1 row in set (0.00 sec)
json_replace、json_set和json_insert示例
- json_replace:只替换已经存在的旧值
- json_set:替换旧值,并插入不存在的新值
- json_insert:插入新值,但不替换已经存在的旧值
替换值,json_replace示例
mysql> UPDATE employees
-> SET data = json_replace(data, '$.name', 'Cathy')
-> WHERE data->'$.id' = 2;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM employees WHERE data->'$.id'= 2;
+---------------------------+
| data |
+---------------------------+
| {"id": 2, "name": "Cathy"} |
+---------------------------+
1 row in set (0.00 sec)
设置值,json_set示例
mysql> UPDATE employees
-> SET data = json_set(data, '$.name', 'Bill', '$.city', '北京')
-> WHERE data->'$.id'= 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM employees WHERE data->'$.id'= 2;
+---------------------------------------------+
| data |
+---------------------------------------------+
| {"id": 2, "city": "北京", "name": "David"} |
+---------------------------------------------+
1 row in set (0.00 sec)
插入值,json_insert示例
mysql> UPDATE employees
-> SET data = json_insert(data, '$.name', 'Will', '$.address', '通州副中心')
-> WHERE data->'$.id'= 2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM employees WHERE data->'$.id'= 2;
+---------------------------------------------------------------------+
| data |
+---------------------------------------------------------------------+
| {"id": 2, "city": "北京", "name": "David", "address": "通州副中心"} |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)