mysql中保存并操作json对象

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mysql中保存并操作json对象

对于最常使用的数据格式 json 而言,数据库 mysql 提供了保存及一系列操作方法供大家使用,下面我们就来学习一下吧。

1.数据类型

mysql5.7 版本之前, json 数据一般使用数据类型 LONGBLOB 或者 LONGTEXT 存储。后来大家「千呼万唤」官方才正式引入了数据类型 JSON

2.创建json类型字段

1) 创建一个测试数据库 testdb

2) 切换到此数据库下

3) 创建一张表 t1,表中包含一个字段 jsondoc ,其字段类型为 JSON

4) 查看表的构建信息

mysql> create database testdb;
Query OK, 1 row affected (0.03 sec)
mysql> use testdb;
Database changed
mysql> create table t1 (jsondoc JSON);
Query OK, 0 rows affected (0.07 sec)
mysql> show create table t1;
+-------+----------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                         |
+-------+----------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `jsondoc` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

3.增删改查

3.1 新增数据

新增三条测试数据

insert into t1 values
    ('{"name":"ethanyan","age":25}'),
    ('{"x": 17, "x": "red"}'),
    ('{"x": 17, "x": "red", "x": [3, 5, 7]}');

当我们插入的 json 中包含多个相同字段,表中只会保存最后一个值。可以看下方查询结果。

mysql> select * from t1;
+---------------------------------+
| jsondoc                         |
+---------------------------------+
| {"age": 25, "name": "ethanyan"} |
| {"x": "red"}                    |
| {"x": [3, 5, 7]}                |
+---------------------------------+
3 rows in set (0.00 sec)

官方文档提示在 8.0.3 版本中有bug,上述同一 json 中相同字段情况,会保存第一个值。小闫使用的版本为8.0.19,此bug已修复,最终效果为保存最后一个值。(按书写的先后顺序确定)

3.2 修改数据

3.2.1 案例一

将数据 {"x": "red"} 修改为 {"name": "hanhan", "age": 12}

update t1 
    set jsondoc='{"name": "hanhan", "age": 12}' 
    where json_extract(jsondoc,"$.x")="red";

1) json_extract() 函数可以根据 JSON Path Syntax 提取json 字符串中所需的键值。第一个参数 jsondocjson 字符串(此处为字段名);第二个参数 $.xJSON Path Syntax (此处的意思为提取键 x 的值)。

2) 整体解读:将表 t1 满足条件的记录中,字段 jsondoc 的值更改为 {"name": "hanhan", "age": 12}。条件:提取 json_docx 值等于 red 的记录。

3.2.2 案例二

将数据 {"x": [3, 5, 7]} 修改为 {"name": "rose", "age": 18}

update t1 
    set jsondoc='{"name": "rose", "age": 18}' 
    where json_extract(jsondoc,"$.x[0]")=3;

可以看出使用的函数、语法与案例一中大致相同,不同的是 JSON Path Syntax

1) 如果 json 字符串中某一键值为数组,我们可以通过下标索引 [n] 的方式提取元素。

n 为下标

2) 整体解读:将表 t1 满足条件的记录中,字段 jsondoc 的值更改为 {"name": "rose", "age": 18}。条件:提取 json_docx 所指向数组下标为0的元素值等于3的记录。

3.3 查询数据

3.3.1 查询全部

我们可以查询全部数据,看上述操作是否已经修改数据。

mysql> select * from t1;
+---------------------------------+
| jsondoc                         |
+---------------------------------+
| {"age": 25, "name": "ethanyan"} |
| {"age": 12, "name": "hanhan"}   |
| {"age": 18, "name": "rose"}     |
+---------------------------------+
3 rows in set (0.00 sec)

3.3.2 查询json中键值对

需求:查询表中字段 jsondocname 的值。

方式一: 使用操作符 ->

mysql> select jsondoc->"$.name" from t1;
+-------------------+
| jsondoc->"$.name" |
+-------------------+
| "ethanyan"        |
| "hanhan"          |
| "rose"            |
+-------------------+
3 rows in set (0.00 sec)

方式二:使用操作符 ->>

mysql> select jsondoc->>"$.name" from t1;
+--------------------+
| jsondoc->>"$.name" |
+--------------------+
| ethanyan           |
| hanhan             |
| rose               |
+--------------------+
3 rows in set (0.00 sec)

方式三:使用函数 json_extract()

mysql> select json_extract(jsondoc,'$.name') from t1;
+--------------------------------+
| json_extract(jsondoc,'$.name') |
+--------------------------------+
| "ethanyan"                     |
| "hanhan"                       |
| "rose"                         |
+--------------------------------+
3 rows in set (0.00 sec)

注意:

1) 可以看出方式一与方式三效果完全一致,方式二结果中没有双引号

2) 操作符 ->->> 的左侧为字段名,右侧为 JSON Path Syntax

3.4 删除数据

最后我们删除一条记录:


delete from t1 where json_extract(jsondoc,"$.name")="rose";

4.有关函数

大家应该发现增删改查其实最大的不同在于:有很多函数的使用。除了函数 json_extract() 外,还有哪些呢?一起来看看。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

4.1 JSON_TYPE

JSON_TYPE函数需要一个 JSON 参数,并尝试将其解析为 JSON 值。如果有效,则返回值的 JSON 类型,否则返回错误。

mysql> select json_type('{"name":"ethanyan"}');
+----------------------------------+
| json_type('{"name":"ethanyan"}') |
+----------------------------------+
| OBJECT                           |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select json_type('[1,"2"]');
+----------------------+
| json_type('[1,"2"]') |
+----------------------+
| ARRAY                |
+----------------------+
1 row in set (0.00 sec)
mysql> select json_type('"hello"');
+----------------------+
| json_type('"hello"') |
+----------------------+
| STRING               |
+----------------------+
1 row in set (0.00 sec)
mysql> select json_type('hello world');
ERROR 3141 (22032): Invalid JSON text in argument 1 to function json_type: "Invalid value." at position 0.

4.2 JSON_ARRAY

此函数会将给定的参数,生成一个数组。

mysql> select json_array('a',1,now());
+----------------------------------------+
| json_array('a',1,now())                |
+----------------------------------------+
| ["a", 1, "2020-03-21 11:50:11.000000"] |
+----------------------------------------+
1 row in set (0.00 sec)

4.3 JSON_OBJECT

此函数会将给定的参数,按照顺序组合为键值对,打包成 json 对象。

mysql> select json_object('name','ethanyan','age',20);
+-----------------------------------------+
| json_object('name','ethanyan','age',20) |
+-----------------------------------------+
| {"age": 20, "name": "ethanyan"}         |
+-----------------------------------------+
1 row in set (0.00 sec)

4.4 JSON_MERGE_PRESERVE

该函数会将多个 json 对象进行合并。

mysql> select json_merge_preserve('[1,2]','{"school":"Qinghua"}');
+-----------------------------------------------------+
| json_merge_preserve('[1,2]','{"school":"Qinghua"}') |
+-----------------------------------------------------+
| [1, 2, {"school": "Qinghua"}]                       |
+-----------------------------------------------------+
1 row in set (0.00 sec)

4.5 JSON_MERGE_PATCH

该函数会将多个 json 对象合并,并去重。我们与函数 4.4 进行比对直观感受一下。

mysql> 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\G
*************************** 1. row ***************************
preserve: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3}
   patch: {"a": 4, "b": 2, "c": 5, "d": 3}
1 row in set (0.00 sec)

4.6 JSON_VALID

验证是否为有效的 json

mysql> select json_valid('{"name":1}');
+--------------------------+
| json_valid('{"name":1}') |
+--------------------------+
|                        1 |
+--------------------------+
1 row in set (0.00 sec)
mysql> select json_valid('null');
+--------------------+
| json_valid('null') |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)
mysql> select json_valid('NULL');
+--------------------+
| json_valid('NULL') |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)

json 中如果为空,可以表示为 "" 或者 null 。请不要写 NULL 或者 Null ,虽然在 sql 语法中可以,但是此数据类型中不行。

4.7 JSON_SET

此函数可以替换现有路径的值,并添加不存在的路径的值。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

比如有一个变量:


set @j = '["a", {"b": [true, false]}, [10, 20]]';

然后我们使用函数进行操作:

mysql> select json_set(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| json_set(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20, 2]]      |
+--------------------------------------------+
1 row in set (0.00 sec)

4.8 JSON_INSERT

添加一个新的键值对,不会更改已经存在的键值对。

mysql> select json_insert(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| json_insert(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {"b": [true, false]}, [10, 20, 2]]      |
+-----------------------------------------------+
1 row in set (0.00 sec)

4.9 JSON_REPLACE

替换已有的键值对,不会添加新的键值对。

mysql> select json_replace(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| json_replace(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20]]             |
+------------------------------------------------+
1 row in set (0.00 sec)

4.10 JSON_REMOVE

接收 JSON 文档和一个或多个指定要从文档中删除的值的路径。返回值是原始文档减去该文档内存在的路径所选择的值。也就是删除指定键值对。

mysql> select json_remove(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| json_remove(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {"b": [true]}]                              |
+---------------------------------------------------+
1 row in set (0.00 sec)

5.注意

1) 通过 JSON_OBJECT 转换的值字符集为 utf8mb4collationutf8mb4_bin

2) utf8mb4 是现在最新版本 mysql 默认的编码格式。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

3) 原来 mysql 支持的 UTF-8 编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。最著名的错误便是 Emoji表情插入报错,还有很多不常用的汉字,以及任何新增的 Unicode 字符报错等等。

Emoji 是一种特殊的 Unicode 编码,常见于 iosandroid 手机上

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
python操作mysql
python操作mysql
|
1月前
|
JSON 关系型数据库 数据库
【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】
【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】
【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】
|
4天前
|
SQL 关系型数据库 MySQL
DQL操作MySql
DQL操作MySql
9 0
|
4天前
|
SQL Java 关系型数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
|
13天前
|
SQL 存储 关系型数据库
【MySQL】DDL的表操作详解:创建&查询&修改&删除
【MySQL】DDL的表操作详解:创建&查询&修改&删除
|
14天前
|
SQL DataWorks 关系型数据库
DataWorks操作报错合集之DataWorks在同步mysql时报错Code:[Framework-02],mysql里面有个json类型字段,是什么原因导致的
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
30 0
|
14天前
|
关系型数据库 MySQL Java
使用shardingjdbc执行MySQL游标操作时报错
使用shardingjdbc执行MySQL游标操作时报错
|
14天前
|
存储 SQL 关系型数据库
mysql查询数据库表大小怎么操作
mysql查询数据库表大小怎么操作
|
14天前
|
SQL 关系型数据库 MySQL
使用Python的pymysql库连接MySQL,执行CRUD操作
使用Python的pymysql库连接MySQL,执行CRUD操作:安装pymysql,然后连接(host='localhost',user='root',password='yourpassword',database='yourdatabase'),创建游标。查询数据示例:`SELECT * FROM yourtable`;插入数据:`INSERT INTO yourtable...`;更新数据:`UPDATE yourtable SET...`;删除数据:`DELETE FROM yourtable WHERE...`。
27 0
|
15天前
|
SQL 关系型数据库 数据库
【MySQL】:DDL数据库定义与操作
【MySQL】:DDL数据库定义与操作
14 0