mysql5.7新特性JSON数据类型解析

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介:

废话不多说,直接上实例。


一、json结构

创建测试表

1
2
3
4
5
6
CREATE  TABLE  `article` (
   `id`  int (11) unsigned  NOT  NULL  AUTO_INCREMENT,
   `category` json  NOT  NULL ,
   `tags` json  NOT  NULL ,
   PRIMARY  KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4  DEFAULT  CHARSET=utf8

分析:article表中的字段category与tags均为json类型


填写测试数据

1
2
3
4
INSERT  INTO  `article`  VALUES 
(1, '{\"id\": 1, \"name\": \"php\"}' , '[\"php\", \"mysql\", \"linux\", \"nginx\", \"redis\", \"memcache\", \"mongodb\"]' ),
(2, '{\"id\": 2, \"name\": \"java\"}' , '[\"java\", \"mysql\", \"oracel\", \"linux\", \"nginx\", \"redis\", \"memcache\", \"mongodb\"]' ),
(3, '{\"id\": \"3\", \"name\": \"c#\"}' , '[\"c\", \"c++\", \"OS\", \"linux\", \"unix\", \"IBM\"]' );


总体预览

1.png



二、json查询

select id,json_extract(category,'$.name') as name from test.article;#提取json字段里面的信息

# column->path形式 访问json中的元素 category->'$.name'
select id,category->'$.name' as name from test.article;#提取json字段里面的信息(访问json中的元素 category->'$.name')
select id,json_unquote(json_extract(category,'$.name')) as name from test.article;#提取json字段里面的信息,json_unqoute去双引号
select id,json_unquote(category->'$.name') as name from test.article;#提取json字段里面的信息,json_unqoute去双引号
select id,category->>'$.name' as name from test.article;

select * from test.article where category='{"id": 1, "name": "php"}'; #json不同于字符串,不能当作字符串做比较

select * from test.article where category=cast('{"id": 1, "name": "php"}' as JSON); #通过CAST将字符串转换成JSON形式


select * from test.article where category->'$.name'='java';

select * from test.article where category->>'$.name'='java';

#JSON 中的元素搜索是严格区分变量类型的,比如说整型和字符串是严格区分的

select * from test.article where category->'$.id'='2';#字符号串

select * from test.article where category->'$.id'=2;#整形

select * from test.article where category->'$.id'='3';#字符号串


select * from test.article where json_extract(category,'$.id')='3';#字符号串

select * from test.article where json_contains(category,'2','$.id');#整数

select * from test.article where json_contains(category,'"3"','$.id');#字符号串


select * from test.article where json_contains(tags,'"linux"');#字符号串


2、查询json格式的字段
mysql> select jsn_extract(data, '.name),jsnextract(data,.address') from user;  
+-----------------------------+-------------------------------+  
| jsn_extract(data, '.name)|jsnextract(data,.address') |  
+-----------------------------+-------------------------------+  
| "David" | "Shangahai" |  
| "Amy" | NULL |  
+-----------------------------+-------------------------------+  
2 rows in set (0.00 sec) 
3、给json格式的某个键字段创建索引。首先创建虚拟列,之后在改虚拟列上创建索引。
mysql> ALTER TABLE user ADD user_name varchar(128)  
    -> GENERATED ALWAYS AS (jsn_extract(data,'$.name')) VIRTUAL;  
Query OK, 0 rows affected (0.01 sec)  
Records: 0 Duplicates: 0 Warnings: 0  
   
mysql> select user_name from user;  
+-----------+  
| user_name |  
+-----------+  
| "Amy"     |  
| "David"   |  
+-----------+  
2 rows in set (0.00 sec)  
   
mysql> alter table user add index idx_username (user_name);  
Query OK, 2 rows affected (0.01 sec)  
Records: 2  Duplicates: 0  Warnings: 0  
4、之后通过虚拟列名对json特定列进行索引查询:
mysql> explain select * from user where user_name='"Amy"'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user
   partitions: NULL
         type: ref
possible_keys: idx_username
          key: idx_username
      key_len: 131
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)


三、json更新


更新 JSON

如果是整个 json 更新的话,和插入时类似的。

mysql> UPDATE lnmp SET tags = '[1, 3, 4]' WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM lnmp;
+----+------------------------------+-----------+ 
| id | category                     | tags      | 
+----+------------------------------+-----------+ 
| 1  | {"id": 1, "name": "lnmp.cn"} | [1, 3, 4] | 
| 2  | {"id": 2, "name": "php.net"} | [1, 3, 5] |
+----+------------------------------+-----------+
2 rows in set (0.00 sec)

但如果要更新 JSON 下的元素,MySQL 并不支持 column->path 的形式

mysql> UPDATE lnmp SET category->'$.name' = 'lnmp', tags->'$[0]' = 2 WHERE id = 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '->'$.name' = 'lnmp', tags->'$[0]' = 2 WHERE id = 1' at line 1

则可能要用到以下几个函数

JSON_INSERT() 插入新值,但不会覆盖已经存在的值

mysql> UPDATE lnmp SET category = JSON_INSERT(category, '$.name', 'lnmp', '$.url', 'www.lnmp.cn') WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------+-----------+
| id | category                                           | tags      |
+----+----------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php.net"}                       | [1, 3, 5] |
+----+----------------------------------------------------+-----------+
2 rows in set (0.00 sec)

可以看到 name 没有被修改,但新元素 url 已经添加进去

JSON_SET() 插入新值,并覆盖已经存在的值

mysql> UPDATE lnmp SET category = JSON_SET(category, '$.host', 'www.lnmp.cn', '$.url', 'http://www.lnmp.cn') WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------------------------------------+-----------+
| id | category                                                                         | tags      |
+----+----------------------------------------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "http://www.lnmp.cn", "host": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php.net"}                                                     | [1, 3, 5] |
+----+----------------------------------------------------------------------------------+-----------+
2 rows in set (0.00 sec)

可以看到 host 已经插入,url 已经被修改

JSON_REPLACE() 只替换存在的值

mysql> UPDATE lnmp SET category = JSON_REPLACE(category, '$.name', 'php', '$.url', 'http://www.php.net') WHERE id = 2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------------------------------------+-----------+
| id | category                                                                         | tags      |
+----+----------------------------------------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "http://www.lnmp.cn", "host": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php"}                                                         | [1, 3, 5] |
+----+----------------------------------------------------------------------------------+-----------+
2 rows in set (0.00 sec)

可以看到 name 已经被替换,url 不存在被忽略。

JSON_REMOVE() 删除 JSON 元素

mysql> UPDATE lnmp SET category = JSON_REMOVE(category, '$.url', '$.host') WHERE id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM lnmp;
+----+------------------------------+-----------+
| id | category                     | tags      |
+----+------------------------------+-----------+
|  1 | {"id": 1, "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php"}     | [1, 3, 5] |
+----+------------------------------+-----------+
2 rows in set (0.00 sec)

更多函数请参考:http://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html

MySQL JSON 在 PHP 中的表现

虽然在 MySQL 是个JSON 类型,但实际在 PHP 应用中返回的是 JSON 格式的字符串

array(2) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "1"
    ["category"]=>
    string(28) "{"id": 1, "name": "lnmp.cn"}"
    ["tags"]=>
    string(9) "[1, 3, 4]"
  }
  [1]=>
  array(3) {
    ["id"]=>
    string(1) "2"
    ["category"]=>
    string(24) "{"id": 2, "name": "php"}"
    ["tags"]=>
    string(9) "[1, 3, 5]"
  }
}









本文转自 hgditren 51CTO博客,原文链接:http://blog.51cto.com/phpme/2057161,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
26天前
|
JSON 前端开发 Java
Json格式数据解析
Json格式数据解析
|
3天前
|
SQL 存储 关系型数据库
【MySQL-6】DDL的表结构的数据类型盘点&案例演示
【MySQL-6】DDL的表结构的数据类型盘点&案例演示
|
4天前
|
SQL DataWorks 关系型数据库
DataWorks操作报错合集之DataWorks在同步mysql时报错Code:[Framework-02],mysql里面有个json类型字段,是什么原因导致的
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
20 0
|
4天前
|
JSON 安全 Swift
【Swift开发专栏】Swift中的JSON解析与处理
【4月更文挑战第30天】本文介绍了Swift中的JSON解析与处理。首先,讲解了JSON的基础,包括其键值对格式和在Swift中的解析与序列化方法。接着,展示了如何使用`Codable`协议简化JSON操作,以及处理复杂结构的示例。通过这些内容,读者能掌握在Swift中高效地处理JSON数据的方法。
|
5天前
|
存储 数据库连接 PHP
【PHP开发专栏】深入解析PHP数据类型与运算符
【4月更文挑战第30天】本文深入探讨了PHP的编程基础——数据类型和运算符。PHP支持整型、浮点型、字符串、布尔型、数组、对象、资源等数据类型。运算符包括算术、字符串、赋值、比较、逻辑、位、错误控制及范围运算符。通过示例展示了如何计算圆面积、判断素数和求斐波那契数列,以帮助读者更好地理解和应用这些概念。
|
5天前
|
存储 SQL 关系型数据库
【mysql】mysql中的数据类型知多少?
【mysql】mysql中的数据类型知多少?
|
5天前
|
分布式计算 DataWorks 关系型数据库
DataWorks产品使用合集之在DataWorks中,使用JSON解析函数将MySQL表中的字段解析成多个字段将这些字段写入到ODPS(MaxCompute)中如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
14 3
|
7天前
|
关系型数据库 MySQL
MySQL基础(二:常用数据类型及MySQL创建过程实例)
MySQL基础(二:常用数据类型及MySQL创建过程实例)
MySQL基础(二:常用数据类型及MySQL创建过程实例)
|
9天前
|
存储 缓存 关系型数据库
【Mysql】Schema与数据类型优化
【Mysql】Schema与数据类型优化
9 0
|
10天前
|
存储 JSON 关系型数据库
MySQL 数据类型剖析
MySQL 数据类型剖析
13 1

推荐镜像

更多