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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

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


一、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,如需转载请自行联系原作者
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
432 9
|
3月前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
3月前
|
存储 关系型数据库 MySQL
double ,FLOAT还是double(m,n)--深入解析MySQL数据库中双精度浮点数的使用
本文探讨了在MySQL中使用`float`和`double`时指定精度和刻度的影响。对于`float`,指定精度会影响存储大小:0-23位使用4字节单精度存储,24-53位使用8字节双精度存储。而对于`double`,指定精度和刻度对存储空间没有影响,但可以限制数值的输入范围,提高数据的规范性和业务意义。从性能角度看,`float`和`double`的区别不大,但在存储空间和数据输入方面,指定精度和刻度有助于优化和约束。
432 5
|
3月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
83 8
|
4月前
|
编译器 PHP 开发者
PHP 8新特性解析与实战应用####
随着PHP 8的发布,这一经典编程语言迎来了诸多令人瞩目的新特性和性能优化。本文将深入探讨PHP 8中的几个关键新功能,包括命名参数、JIT编译器、新的字符串处理函数以及错误处理改进等。通过实际代码示例,展示如何在现有项目中有效利用这些新特性来提升代码的可读性、维护性和执行效率。无论你是PHP新手还是经验丰富的开发者,本文都将为你提供实用的技术洞察和最佳实践指导。 ####
62 1
|
4月前
|
关系型数据库 MySQL
mysql事务特性
原子性:一个事务内的操作统一成功或失败 一致性:事务前后的数据总量不变 隔离性:事务与事务之间相互不影响 持久性:事务一旦提交发生的改变不可逆
|
4月前
|
数据安全/隐私保护 iOS开发 开发者
iOS 14隐私保护新特性深度解析####
随着数字时代的到来,隐私保护已成为全球用户最为关注的问题之一。苹果在最新的iOS 14系统中引入了一系列创新功能,旨在增强用户的隐私和数据安全。本文将深入探讨iOS 14中的几大隐私保护新特性,包括App跟踪透明度、剪贴板访问通知和智能防追踪功能,分析这些功能如何提升用户隐私保护,并评估它们对开发者和用户体验的影响。 ####
|
4月前
|
PHP 开发者
PHP 7新特性深度解析
【10月更文挑战第40天】随着PHP 7的发布,这个广泛使用的语言带来了许多令人兴奋的新特性和性能改进。本文将深入探讨PHP 7的主要变化,包括类型声明、错误处理机制、性能优化等方面,帮助开发者更好地理解和应用这些新特性。
55 5
|
4月前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
270 3
|
4月前
|
存储 关系型数据库 MySQL
MySQL 8.0特性-自增变量的持久化
【11月更文挑战第8天】在 MySQL 8.0 之前,自增变量(`AUTO_INCREMENT`)的行为在服务器重启后可能会发生变化,导致意外结果。MySQL 8.0 引入了自增变量的持久化特性,将其信息存储在数据字典中,确保重启后的一致性。这提高了开发和管理的稳定性,减少了主键冲突和数据不一致的风险。默认情况下,MySQL 8.0 启用了这一特性,但在升级时需注意行为变化。
110 1

热门文章

最新文章

推荐镜像

更多