[Database] MySQL 5.7+ JSON 字段的使用的处理

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: [Database] MySQL 5.7+ JSON 字段的使用的处理

简介

MySQL5.7.x增加了对JSON字段的支持,根据官方文档 一下常用的操作摘取

在这里插入图片描述

方法 / 步骤

一: 创建测试数据

在 MySQL 8.0.13 之前,不允许对 BLOB,TEXT,GEOMETRY,JSON 字段设置默认值。从 MySQL 8.0.13 开始,取消了这个限制。

# 创建表
CREATE TABLE `goods` (
  `goods_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `goods_name` varchar(55) DEFAULT NULL COMMENT '商品名称',
  `goods_attrs` text COMMENT '商品属性例如:{"color":"red","size":100,"sex":"famale"}',
  `support_store_ids` text COMMENT '支持门店id 格式:["10000","20000","30000"]',
  PRIMARY KEY (`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';

# 初始化数据
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (1, '5店通用女生VIP卡', '{\"type\":\"通店\",\"sex\":\"famale\"}', '[\"001\",\"002\",\"003\",\"004\",\"005\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (2, '5店通用男生VIP卡', '{\"type\":\"通店\",\"sex\":\"male\"}', '[\"001\",\"002\",\"003\",\"004\",\"005\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (3, '门店1男生卡', '{\"type\":\"门店1\",\"sex\":\"male\"}', '[\"001\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (4, '门店2男生卡', '{\"type\":\"门店2\",\"sex\":\"nomal\"}', '[\"002\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (5, '门店3男生卡', '{\"type\":\"门店3\",\"sex\":\"nomal\"}', '[\"003\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (6, '门店1女生卡', '{\"type\":\"门店1\",\"sex\":\"famale\"}', '[\"001\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (7, '门店2女生卡', '{\"type\":\"门店2\",\"sex\":\"famale\"}', '[\"002\"]');
INSERT INTO `goods`(`goods_id`, `goods_name`, `goods_attrs`, `support_store_ids`) VALUES (8, '门店3女生卡', '{\"type\":\"门店3\",\"sex\":\"famale\"}', '[\"003\"]');

在这里插入图片描述

1.1 新增操作

  • 手动插入Json类型的记录
INSERT INTO `goods` ( `goods_id`, `goods_name`, `goods_attrs`, `support_store_ids` )
VALUES ( NULL,'一二门店男生卡', JSON_OBJECT( "type", "门店12", "sex", "male" ), JSON_ARRAY( "001", "002" ))

# 数组追加字段
SELECT JSON_ARRAY_APPEND(support_store_ids, '$', "006") FROM goods WHERE goods_id = 1

二:查询操作

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

  • 普通List查询
 # 查询001店能购买的商品
 # 要特别注意的是,JSON 中的元素搜索是严格区分变量类型的,
 # 比如说整型和字符串是严格区分的,即 "001"和001
SELECT * FROM goods WHERE JSON_CONTAINS(support_store_ids, '"001"')

# 查询属性type是通店的的记录
# //用JSON_CONTAINS 函数,但和 *column->path *的形式有点相反的是,JSON_CONTAINS 第二个参数是不接受整数的,无论 json 元素是整型还是字符串,否则会出现错误

SELECT * FROM goods WHERE JSON_CONTAINS(goods_attrs, '"通店"', '$.type')

 # 查询001 和 002 店能购买的商品
 SELECT * FROM goods WHERE JSON_CONTAINS(support_store_ids, '"001"') OR JSON_CONTAINS(support_store_ids, '"002"')
一般对应字符串类型的 category->’$.name’ 中还包含着双引号,这其实并不是想要的结果,可以用 JSON_UNQUOTE 函数将双引号去掉,从 MySQL 5.7.13 起也可以通过这个操作符 ->> 这个和 JSON_UNQUOTE 是等价的
# 查找type字段中key属性是通店的记录
SELECT * FROM goods WHERE goods_attrs->'$.type'='通店';

# 查询json的值,即键的值
SELECT
    goods_id,
    goods_name,
    goods_attrs -> '$.type' AS type_name,
    JSON_UNQUOTE( goods_attrs -> '$.type' ) 
FROM goods WHERE goods_attrs -> '$.type' = '通店';

在这里插入图片描述

三:更新 / 删除

#更新数组按以往的更新就行
UPDATE goods SET support_store_ids = '["001","002"]' WHERE goods_id = 6

但如果要更新 JSON 下的元素,MySQL 并不支持 column->path的形式,则可能要用到以下几个函数

3.1 JSON_INSERT()

  • JSON_INSERT() 插入新值,但不会覆盖已经存在的值
-- 追加新的键值
UPDATE goods SET goods_attrs = JSON_INSERT(goods_attrs,'$.type1','通店111') WHERE goods_id = 6

在这里插入图片描述

3.2 JSON_SET()

  • JSON_SET() 插入新值,并覆盖已经存在的值
UPDATE goods SET goods_attrs = JSON_SET(goods_attrs,'$.type','门店666') WHERE goods_id = 6

在这里插入图片描述

3.3 JSON_REPLACE()

  • JSON_REPLACE() 只替换存在的值
UPDATE goods SET goods_attrs = JSON_REPLACE(goods_attrs,'$.type','门店777') WHERE goods_id = 6

在这里插入图片描述

3.4 JSON_REMOVE()

  • JSON_REMOVE() 删除 JSON 元素
UPDATE goods SET goods_attrs = JSON_REMOVE(goods_attrs, '$.type','$.type1') WHERE goods_id = 6;

在这里插入图片描述

参考资料 & 致谢

[1] 官方文档
[2] MySQL的json查询

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3天前
|
SQL 关系型数据库 MySQL
MySQL数据库中给表添加字段并设置备注的脚本编写
通过上述步骤,你可以在MySQL数据库中给表成功添加新字段并为其设置备注。这样的操作对于保持数据库结构的清晰和最新非常重要,同时也帮助团队成员理解数据模型的变化和字段的具体含义。在实际操作中,记得调整脚本以适应具体的数据库和表名称,以及字段的详细规范。
19 8
|
25天前
|
存储 JSON 关系型数据库
MySQL与JSON的邂逅:开启大数据分析新纪元
MySQL与JSON的邂逅:开启大数据分析新纪元
|
7天前
|
SQL 关系型数据库 MySQL
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
21 0
|
1月前
|
存储 SQL 关系型数据库
在 MySQL 中使用 Drop Database
【8月更文挑战第11天】
94 0
在 MySQL 中使用 Drop Database
|
30天前
|
SQL 关系型数据库 MySQL
mysql不等于<>取特定值反向条件的时候字段有null值或空值读取不到数据
对于数据库开发的专业人士来说,理解NULL的特性并知道如何正确地在查询中处理它们是非常重要的。以上所介绍的技巧和实例可以帮助你更精准地执行数据库查询,并确保数据的完整性和准确性。在编写代码和设计数据库结构时,牢记这些细节将有助于你避免许多常见的错误,提高数据库应用的质量与性能。
33 0
|
2月前
|
关系型数据库 MySQL
mysql使用 CONCAT(字段,字段) 函数拼接
mysql使用 CONCAT(字段,字段) 函数拼接
|
2月前
|
存储 SQL 缓存
MySQL设计规约问题之为什么要将大字段、访问频率低的字段拆分到单独的表中存储
MySQL设计规约问题之为什么要将大字段、访问频率低的字段拆分到单独的表中存储
|
2月前
|
SQL 存储 索引
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
|
2月前
|
关系型数据库 MySQL
MySQL设计规约问题之表示是与否概念的字段应该如何命名
MySQL设计规约问题之表示是与否概念的字段应该如何命名
|
3天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。