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

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: [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
目录
相关文章
|
8天前
|
存储 SQL 关系型数据库
在 MySQL 中使用 Drop Database
【8月更文挑战第11天】
49 0
在 MySQL 中使用 Drop Database
|
1月前
|
关系型数据库 MySQL 数据库
MySQL 保姆级教程(八):创建计算字段
MySQL 保姆级教程(八):创建计算字段
|
1月前
|
关系型数据库 MySQL
mysql使用 CONCAT(字段,字段) 函数拼接
mysql使用 CONCAT(字段,字段) 函数拼接
|
29天前
|
存储 SQL 缓存
MySQL设计规约问题之为什么要将大字段、访问频率低的字段拆分到单独的表中存储
MySQL设计规约问题之为什么要将大字段、访问频率低的字段拆分到单独的表中存储
|
29天前
|
SQL 存储 索引
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
|
29天前
|
关系型数据库 MySQL
MySQL设计规约问题之表示是与否概念的字段应该如何命名
MySQL设计规约问题之表示是与否概念的字段应该如何命名
|
2月前
|
JSON 关系型数据库 MySQL
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
39 1
|
1月前
|
关系型数据库 MySQL 数据库
Relational Database Service RDS 各个版本
【7月更文挑战第12天】
26 0
|
2月前
|
存储 JSON 关系型数据库
MySQL JSON 类型:功能与应用
MySQL JSON 类型:功能与应用
|
3月前
|
SQL 存储 关系型数据库
MySQL技能完整学习列表——1、数据库基础概念——1、关系型数据库(Relational Database)
MySQL技能完整学习列表——1、数据库基础概念——1、关系型数据库(Relational Database)
207 0