MySQL 学习笔记 JSON 类型

Posted 笑虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 学习笔记 JSON 类型相关的知识,希望对你有一定的参考价值。

mysql 学习笔记 JSON 类型

Name说明
->从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()已弃用的同义词 Deprecated
JSON_MERGE_PATCH()合并JSON文档,替换重复键的值
JSON_MERGE_PRESERVE()合并JSON文档,保留重复键
JSON_OBJECT()创建JSON对象
JSON_OVERLAPS()比较两个JSON文档,如果它们有任何共同的键值对或数组元素,则返回TRUE(1),否则返回FALSE (0) + 8.0.17
JSON_PRETTY()以人类可读的格式打印JSON文档
JSON_QUOTE()引用JSON文档
JSON_REMOVE()从JSON文档中删除数据
JSON_REPLACE()替换JSON文档中的值
JSON_SCHEMA_VALID()根据JSON模式验证JSON文档;如果文档对模式进行验证,则返回TRUE/1,否则返回FALSE/0 + 8.0.17
JSON_SCHEMA_VALIDATION_REPORT()根据JSON模式验证JSON文档;返回JSON格式的验证结果报告,包括成功或失败和失败的原因 + 8.0.17
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()从JSON文档中提取由路径提供的指向位置的值;返回该值为VARCHAR(512)或指定的类型 + 8.0.21
MEMBER OF()如果第一个操作数与JSON数组中作为第二个操作数传递的任何元素匹配,则返回true(1),否则返回false (0) + 8.0.17

创建表

CREATE TABLE `poem` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `info` json DEFAULT NULL COMMENT 'JSON数据',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='笑虾原创诗词表';

创建 JSON 值

JSON_OBJECT

JSON_OBJECT([key, val[, key, val] ...])
将字符串,解析为JSON对象。以JSON对象的形势插入。

INSERT INTO `demo`.`poem` (`id`, `info`, `update_time`, `create_time`) 
VALUES (
	1, 
	JSON_OBJECT(
			"title", "笑虾",
			"author", "笑虾",
			"content", "天上游龙水中蛟,不羡高飞入云霄。生来无事终天笑,未曾到老先弯腰。",
			"published_time", "2021-02-16 16:22:23"
		),
	'2022-10-16 14:22:17',
	'2022-10-16 14:07:25'
);

JSON_ARRAY

JSON_ARRAY([val[, val] ...])
将字符串,解析为JSON数组。以JSON数组的形势插入。

INSERT INTO `demo`.`poem` (`id`, `info`, `update_time`, `create_time`) 
VALUES (
	1, 
	JSON_ARRAY (
			"title", "笑虾",
			"author", "笑虾",
			"content", "天上游龙水中蛟,不羡高飞入云霄。生来无事终天笑,未曾到老先弯腰。",
			"published_time", "2021-02-16 16:22:23"
		),
	'2022-10-16 14:22:17',
	'2022-10-16 14:07:25'
);

JSON_QUOTE 转义字符

JSON_QUOTE(string)
content字段转义后再插入。

INSERT INTO `demo`.`poem` (`id`, `info`, `update_time`, `create_time`) 
VALUES (
	2, 
	JSON_OBJECT(
			"title", "笑虾",
			"author", "笑虾",
			"content", JSON_QUOTE("天上游龙水中蛟,不羡高飞入云霄。生来无事终天笑,未曾到老先弯腰。"),
			"published_time", "2021-02-16 16:22:23"
		),
	'2022-10-16 14:22:17',
	'2022-10-16 14:07:25'
);

查询 JSON 值

JSON_CONTAINS 判断包含值

JSON_CONTAINS(target, candidate[, path])

  1. 如果 target 的指定路径 $.a 中存在 1 则返回 1
SELECT JSON_CONTAINS('"a": 1, "b": 2, "c": "d": 4', '1', '$.a') as 字段;
+--------+
| 字段   |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
  1. 如果 target 的指定路径 '$.a' 中不存在值 2 返回 0
mysql> SELECT JSON_CONTAINS('"a": 1, "b": 2, "c": "d": 4', '2', '$.a') as 字段;
+--------+
| 字段   |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)
  1. 如果 $.sss 不存在返回 null
SELECT JSON_CONTAINS('"a": 1, "b": 2, "c": "d": 4', '1', '$.sss') as 字段;
+--------+
| 字段   |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)

JSON_CONTAINS_PATH 判断包含路径

JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)

  1. json_doc 中查找所有 path 只要有一个匹配,就返回 1
mysql> SELECT
    -> JSON_CONTAINS_PATH('"a": 1, "b": 2, "c": "d": 4', 'one', '$.a', '$.e') as a,
    -> JSON_CONTAINS_PATH('"a": 1, "b": 2, "c": "d": 4', 'one', '$.c.d') as b,
    -> JSON_CONTAINS_PATH('"a": 1, "b": 2, "c": "d": 4', 'one', '$.a.d') as c;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    1 |    1 |    0 |
+------+------+------+
1 row in set (0.00 sec)
  1. json_doc 中查找所有 path 全部匹配,就返回 1
SELECT JSON_CONTAINS_PATH('"a": 1, "b": 2, "c": "d": 4', 'all', '$.a', '$.e') as 字段;
+--------+
| 字段   |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)

JSON_EXTRACT(简写 ->)提取值

JSON_EXTRACT(json_doc, path[, path] ...)

SELECT * FROM poem WHERE info -> '$.author' = "笑虾";
SELECT * FROM poem WHERE JSON_UNQUOTE(JSON_EXTRACT(info, "$.author")) = "笑虾";
  1. -> 等同于 JSON_EXTRACT
mysql> SELECT
    -> info -> "$.title" as title1,
    -> JSON_EXTRACT(info, "$.title") as title2
    -> FROM poem;
+----------+----------+
| title1   | title2   |
+----------+----------+
| "笑虾"   | "笑虾"   |
+----------+----------+
1 row in set (0.00 sec)
  1. ->> 等同于 JSON_UNQUOTE(JSON_EXTRACT(json, "path"))
mysql> SELECT
    -> info ->> "$.title" as title1,
    -> JSON_UNQUOTE(JSON_EXTRACT(info, "$.title")) as title2
    -> FROM poem;
+--------+--------+
| title1 | title2 |
+--------+--------+
| 笑虾   | 笑虾   |
+--------+--------+
1 row in set (0.00 sec)

JSON_KEYS 返回所有键

JSON_KEYS(json_doc[, path])
返回路径上所有 KEY 的数组。

SELECT JSON_KEYS('"a": 1, "b": "c": 30') as 列名;
+------------+
| 列名       |
+------------+
| ["a", "b"] |
+------------+
1 row in set (0.00 sec)
SELECT JSON_KEYS('"a": 1, "b": "c": 30', '$.b') as 列名;
+--------+
| 列名   |
+--------+
| ["c"]  |
+--------+
1 row in set (0.00 sec)

JSON_VALUE 返回值

JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error])

参数介绍
json_doc是一个有效的JSON格式。如果这是NULL,函数返回NULL
path指向 JSON 中某个位置的路径。这必须是一个字符串文字值。
type支持的类型 FLOAT,DOUBLE,DECIMAL,SIGNED,UNSIGNED,DATE,TIME,DATETIME,YEAR,CHAR,JSON

json_doc 中给定的 path 提取值,并将其转换为所需类型返回。

mysql> SELECT JSON_VALUE(info, '$.title' RETURNING CHAR) as title FROM poem;
+--------+
| title  |
+--------+
| 笑虾   |
+--------+
1 row in set (0.00 sec)

等同

SELECT CAST( JSON_UNQUOTE( JSON_EXTRACT( info, '$.title') ) AS CHAR ) as title
FROM poem;
+--------+
| title  |
+--------+
| 笑虾   |
+--------+
1 row in set (0.00 sec)

等同

SELECT CAST( info ->> '$.title' AS CHAR ) as title FROM poem;
+--------+
| title  |
+--------+
| 笑虾   |
+--------+
1 row in set (0.00 sec)

JSON_OVERLAPS 对比JSON

JSON_OVERLAPS(json_doc1, json_doc2) MySQL 8.0.17. 加入

  • 判断两个JSON,有交集返回 1 否则 0
mysql> SELECT
    -> JSON_OVERLAPS("[1,3,5,7]", "[2,5,7]") as 字段1,
    -> JSON_OVERLAPS("[1,3,5,7]", "[2,6,7]") as 字段2,
    -> JSON_OVERLAPS("[1,3,5,7]", "[2,6,8]") as 字段3;
+---------+---------+---------+
| 字段1   | 字段2   | 字段3   |
+---------+---------+---------+
|       1 |       1 |       0 |
+---------+---------+---------+
1 row in set (0.00 sec)
  • 元素之间比较要完全相等才算相同。
mysql> SELECT JSON_OVERLAPS('[[1,2],[3,4],5]', '[1,[2,3],[4,5]]') as 字段;
+--------+
| 字段   |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)
  • Object 对比,至少一对 key-value 相同返回 1
mysql> SELECT
    -> JSON_OVERLAPS('"a":1,"b":2,"c":3', '"a":1,"b":2,"c":3') as 字段,
    -> JSON_OVERLAPS('"a":1,"b":2,"c":3', '"a":11,"b":22,"cc":3') as 字段;
+--------+--------+
| K:V相同| V 不同  |
+--------+--------+
|      1 |      0 |
+--------+--------+
1 row in set (0.00 sec)
  • 类型都相等才返回 1
mysql> SELECT
    -> JSON_OVERLAPS('[1,2,3,4]', '1') as 相同,
    -> JSON_OVERLAPS('[1,2,3,4]', '"1"') as 不同;
+--------+--------+
| 相同   | 不同   |
+--------+--------+
|      1 |      0 |
+--------+--------+
1 row in set (0.00 sec)

JSON_SEARCH 返回匹配路径

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])

  1. 返回 JSON 中给定字符串的路径
  2. 返回NULL
    2.1. 如果任何 json_docsearch_strpath参数为 NULL,返回NULL;
    2.2. 如果 search_strpath 未找到,返回NULL;
  3. 如果 json_doc 参数不是一个有效的 JSON,任何路径参数不是一个有效的路径表达式,one_or_all 不是'one''all',或者escape_char不是一个常量表达式,就会发生错误。
  4. search_str 搜索字符串参数中,%_字符与LIKE操作符一样:
    4.1. %匹配任意数量的字符(包括0个字符)
    4.2. 而_刚好匹配一个字符
  5. 要在搜索%_字符,需要转义字符\\
  6. 如果 escape_char 参数缺失或为 NULL,默认值为\\。 否则,escape_char 必须为或一个字符常量参见第12.8.1节“字符串比较函数和操作符”中LIKE的描述
  7. 有关 MySQL 支持的 JSON 路径语法的更多信息,包括控制通配符***的规则,请参阅JSON路径语法
    7.1. .*表示对象中所有成员的值。
    7.2. [*]表示数组中所有单元格的值。
    7.3. [prefix]**suffix 表示所有以 prefix 开头,以 suffix 结尾的路径。前缀可选,后缀必填。
SET @json = '["abc", ["k": "10", "def"], "x":"abc", "y":"bcd"]';
  • one 返回第一个路径
mysql> SELECT JSON_SEARCH(@json, 'one', 'abc') as 字段;
+--------+
| 字段   |
+--------+
| "$[0]" |
+--------+
1 row in set (0.00 sec)
  • all 返回全部符合的路径
mysql> SELECT JSON_SEARCH(@json, 'all', 'abc') as 字段;
+--------------------+
| 字段               |
+--------------------+
| ["$[0]", "$[2].x"] |
+--------------------+
1 row in set (0.00 sec)
  • 666 找不到返回 null
mysql> SELECT JSON_SEARCH(@json, 'one', '666') as 字段;
+--------+
| 字段   |
+--------+
| NULL   |
+--------+
1 row in set (0.00 sec)
  • 10 找到了
mysql> SELECT JSON_SEARCH(@json, 'all', '10') as 字段;
+-------------+
| 字段        |
+-------------+
| "$[1][0].k" |
+-------------+
1 row in set (0.00 sec)
  • ** 任意路径
mysql> SELECT
    -> JSON_SEARCH(@json, 'all', '%', NULL, '$**.k') as a,
    -> JSON_SEARCH(@json, 'all', '%', NULL, '$**[0]') as c,
    -> JSON_SEARCH(@json, 'all', '%', NULL, '$**.x') as b,
    -> JSON_SEARCH(@json, 'all', '%', NULL, '$**.y') as d;
+-------------+-----------------------+----------+----------+
| a           | c                     | b        | d        |
+-------------+-----------------------+----------+----------+
| "$[1][0].k" | ["$[0]", "$[1][0].k"] | "$[2].x" | "$[3].y" |
+-------------+-----------------------+----------+----------+
1 row in set (0.00 sec)

MEMBER OF 数组中匹配元素

value MEMBER OF(json_array)

  1. 如果 valuejson_array 的一个元素,则返回1,否则返回0value 必须是一个标量或JSON;如果它是标量,操作符将尝试将其作为JSON数组的一个元素处理。如果 valuejson_arrayNULL,函数返回 NULL
  2. WHERE 子句中使用 MEMBER OF()InnoDB 表的 JSON 列的查询可以使用多值索引进行优化。有关详细信息和示例,请参阅多值索引。
  3. 简单标量被视为数组值,如下所示:
mysql> SELECT 17 MEMBER OF('[23, "abc", 17, "ab", 10]') as 字段;
+--------+
| 字段   |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
mysql> SELECT 'ab' MEMBER OF('[23, "abc", 17, "ab", 10]') as 字段;
+--------+
| 字段   |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
  • 类型不同,不匹配。
mysql> SELECT
    -> 17 MEMBER OF('[23, "abc", "17", "ab", 10]') as a,
    -> "17" MEMBER OF('[23, "abc", 17, "ab", 10]') as b;
+---+---+
| a | b |
+---+---+
| 0 | 0 |
+---+---+
1 row in set (0.00 sec)
mysql> SELECT
    ->

以上是关于MySQL 学习笔记 JSON 类型的主要内容,如果未能解决你的问题,请参考以下文章

MySQL数据类型 - JSON数据类型

TensorFlow学习笔记2——数据类型及简单运算

JavaScript DOM编程艺术-学习笔记(第二章)

直上云霄!终于有阿里架构师熬夜肝出了443页TCP/IP网络协议笔记

day5-Python学习笔记json数据类型

MongoDB学习笔记-数据格式及数据类型