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])
- 如果
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)
- 如果
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)
- 如果
$.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] ...)
- 在
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)
- 在
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")) = "笑虾";
->
等同于 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)
->>
等同于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] ...])
- 返回
JSON
中给定字符串的路径
。 - 返回
NULL
2.1. 如果任何json_doc
、search_str
或path
参数为NULL
,返回NULL
;
2.2. 如果search_str
或path
未找到,返回NULL
; - 如果
json_doc
参数不是一个有效的JSON
,任何路径参数不是一个有效的路径表达式,one_or_all
不是'one'
或'all'
,或者escape_char
不是一个常量表达式,就会发生错误。 - 在
search_str
搜索字符串参数中,%
和_
字符与LIKE
操作符一样:
4.1.%
匹配任意数量的字符(包括0个字符)
4.2. 而_
刚好匹配一个字符 - 要在搜索
%
或_
字符,需要转义字符\\
。 - 如果
escape_char
参数缺失或为NULL
,默认值为\\
。 否则,escape_char
必须为空
或一个字符常量
。 参见第12.8.1节“字符串比较函数和操作符”中LIKE的描述。 - 有关
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)
- 如果
value
是json_array
的一个元素,则返回1
,否则返回0
。value
必须是一个标量或JSON
;如果它是标量,操作符将尝试将其作为JSON数组的一个元素处理。如果value
或json_array
为NULL
,函数返回NULL
。 - 在
WHERE
子句中使用MEMBER OF()
对InnoDB
表的JSON
列的查询可以使用多值索引进行优化。有关详细信息和示例,请参阅多值索引。 - 简单标量被视为数组值,如下所示:
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 类型的主要内容,如果未能解决你的问题,请参考以下文章