`

【MySQL】处理JSON数据

 
阅读更多

业务需要灵活的数据结构

通常,我们在使用MySQL这类关系型数据库时,会遵守一些准则来设计表结构。

但实际应用场景与“严格的单一准则”是有差距的。因为实际情况中需要考虑多方面的平衡作出妥协。

如,我们刚学完数据库原理时,往往会倾向于努力设计满足BC范式的表结构,或者至少是满足第三范式的表结构。

但当我们在解决实际工程问题时,可能会作出一些无法满足这些范式要求的表结构设计决议。这些设计在当时可能是一个不错的选择(即使事后我们可能会对自己大肆批判)。

如,我们可能会将“start_time”、“end_time”和“elapsed”三个字段共存,其中 elapsed = end_time - start_time 以减少计算量。这就不满足第三范式了

如,我们可能会让“user_id”和“user_name”这两个字段在task记录中共存,以减少连表查询。这就不满足第二范式了

而我们现在要说的JSON类型的字段则导致了“表中表”,不满足第一范式。

 

因为SQL(Structured Query Language,结构化查询语言)式的数据操作方式比较固化,而现实应用中又经常出现灵活性的需求。

虽然有各种NoSQL数据库可以解决很多这方面的问题,但出于各方面成本的考量,有时候我们会将数据都存在MySQL中。即,给部分数据各自分配一个字段固化,并留一个字段存储其它数据复合后的值。

如,对于一个Task表,我们可以将 'id','name',‘type’ 等数据各自分配一个字段固化,

而 'arg' 的结构因为 'type' 的不同也会不同,所以我们可以设置一个 'arg' 字段,存储Task各项参数复合后的数据。

我们可以自定义对这些复合数据字段的解析规则(也就是序列化和反序列化)。当然更多的是选取JSON作为这类字段的数据结构标准。

 

MySQL JSON 类型字段

以前,我们一般选用 MySQL 的 VARCHAR 或 TEXT 等作为这类复合数据字段的类型。

从5.7.8开始,MySQL将 JSON 作为标准的字段类型之一。

与JSON格式的纯文本字段相比,JSON类型的字段有以下优势:

  • 自动校验JSON格式。如果添加的数据不符合JSON规范将会报错。
    • 注意:MySQL中合法的JSON字符串格式与我们通常处理的JSON数据可能有些不同。某些场景下,我们习惯将JSON字符串解析成对象({...})或数组([...]),而不考虑单个值的情况(如:“1”)。
  • 存储格式经过优化。读取JSON内容项的速度更快。
    • 因为MySQL提供的内部数据结构允许通过内容项的key或index直接访问目标数据,而无需将处理其它数据。比以前的上层应用读取整块内容再解析的方式更快。

注:

  • 虽然JSON字段可以存储的数据量很大,但它也受 max_allowed_packet 的限制
  • 不能为JSON字段指定默认值,即JSON字段默认值是NULL
  • 虽然可以通过JSON_EXTRACT方法创建Generated Column字段,再通过该字段创建索引。
    • 但这种做法的意义值得商榷,因为既然把该字段的信息放入JSON字段,可能意味着它并不是一个值得固化的标准属性字段,即使它是Generated Column也显得“污染”太重。

示例

创建表

 

CREATE TABLE `t1` (
  `id` INT NOT NULL,
  `f1` VARCHAR(45) NULL,
  `f2` JSON NULL,
  PRIMARY KEY (`id`));

 

 

创建 JSON 字段数据

  • 方式1:直接将序列化后的JSON文本存入字段
insert into t1 values (1, 'alpha', '{"a":1, "b":"two"}');

 

 

insert into t1 values (1, 'alpha', JSON_OBJECT("a", 1, "b", "two"));
insert into t1 values (2, 'beta', JSON_ARRAY("i1", 2, 3.4));
insert into t1 values (
  1,
  'alpha',
  JSON_MERGE(
    '{"a":1}',
    '{"b":"two"}'
  )
);
insert into t1 values (
  1,
  'alpha',
  JSON_MERGE(
    JSON_OBJECT("a", 1),
    JSON_OBJECT("b", "two")
  )
);
insert into t1 values (
  1,
  'alpha',
  JSON_MERGE(
    JSON_OBJECT("a", 1),
    '{"b": "two"}'
  )
);

 

 

注:

  • 从 MySQL 5.7.22 开始,JSON_MERGE 被 JSON_MERGE_PRESERVE 替代
  • 记得规划好JSON字段内部的业务数据结构,不要被自己搞混
    • 另外,可通过 JSON_TYPE 方法查看JSON字段的类型
select f2, JSON_TYPE(f2) from t1;
+----------------------+---------------+
| f2                   | json_type(f2) |
+----------------------+---------------+
| {"a": 1, "b": "two"} | OBJECT        |
| ["1", 2, 3.4]        | ARRAY         |
+----------------------+---------------+

 

读取 JSON 字段中的内容项

  • 可通过 JSON_EXTRACT 方法获取 JSON 字段中的某部分数据

 

select f2 from t1 where json_extract(f2, '$.b') = 'two';
+----------------------+
| f2                   |
+----------------------+
| {"a": 1, "b": "two"} |
+----------------------+

 

  • 或使用 JSON_EXTRACT 方法的简化形式 ‘->’

 

select f2 from t1 where f2->'$[1]' = 2;
+---------------+
| f2            |
+---------------+
| ["1", 2, 3.4] |
+---------------+

 

 

更改 JSON 字段中的内容项

除了直接将序列化后的JSON文本存入字段外,还可以使用 JSON_INSERTJSON_REPLACEJSON_SETJSON_ARRAY_INSERT 等方法满足不同的需求

 

update t1 set f2 = JSON_INSERT(f2, '$.c', '3') where id=1;
update t1 set f2 = JSON_REPLACE(f2, '$.c', '1+1+1') where id=1;
update t1 set f2 = JSON_SET(f2, '$.c', '1+2') where id=1;

 

  • JSON_INSERT:增加内容项;如果内容项(key)已存在,则不做任何改动
  • JSON_REPLACE:替换内容项;如果内容项(key)不存在,则不做任何改动
  • JSON_SET:设置内容项;如内容项(key)已存在,则替换原值;如果内容项(key)不存在,则添加该内容项

因为有时候JSON字段的原值可能是 NULL(JSON字段默认值是NULL),所以上述方法会失效。这时可以使用 COALESCE 方法指定一个初始值。

 

update t1 set f2 = JSON_SET(COALESCE(f2, '{}'), '$.a', '1') where id=3;

 

 

删除 JSON 字段中的内容项

通过 JSON_REMOVE 方法删除内容项

 

update t1 set f2 = JSON_REMOVE(f2, '$.c') where id=1;

 

*修改部分内容

MySQL 8 会对JSON字段部分内容的修改操作进行优化,它是真的只修改部分内容项,而不是创建一个新的整字段值做整体替换。

 

但是条件比较苛刻:

  • 所更新的字段必须是JSON类型
  • 只能通过 JSON_SET、JSON_REPLACE、JSON_REMOVE 这三个方法对字段进行赋值
  • 且这些方法的输入字段必须是要更新的那个字段
  • 更新操作只能是操作已有的内容项,不能增加内容项
  • 新字段值所占用的存储空间不能比原值多(如果目标字段原来所剩的空间足以满足新增的空间需求,也符合优化条件)

如果将系统变量 binlog_row_value_options 设置为 PARTIAL_JSON,这些部分内容修改的操作也会被记录到 Binary Log 中。

 

 

 

更多MySQL JSON 方法:More

JSON值的比较与排序:Comparison and Ordering of JSON Values (可考虑使用 CAST 方法作为辅助)

分享到:
评论

相关推荐

    mysql一个插件json

    使用这样的插件可以极大地提升MySQL处理JSON数据的灵活性。例如,用户可以自定义函数来搜索嵌套的JSON对象,或者进行复杂的JSON数组操作,这些在标准函数中可能并不直接支持。另外,插件可能还提供了性能优化,对于...

    MySQL数据生成JSON数据

    在实际应用中,这个过程可能需要结合编程语言(如Python、Java、PHP等)来完成,通过数据库驱动或ORM框架与MySQL交互,然后处理生成的JSON数据。这样的操作在Web开发、数据分析等领域非常常见。

    mysql navicat premium,最新版本,支持mysql5.7 json格式数据,解压即可直接使用

    MySQL 5.7是MySQL数据库的一个重大更新,其中引入了对JSON数据类型的内置支持。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于前后端数据传输。MySQL 5.7引入的JSON字段类型允许存储JSON...

    mysql5.7支持json数据的增删改查的例子

    MySQL 5.7版本引入了对JSON数据类型的官方支持,这是一个重要的里程碑,因为它标志着关系型数据库开始更加灵活地处理非结构化数据。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于Web服务和...

    ThinkPHP6.0以上兼容mysql下JSON_CONTAINS使用

    总结,ThinkPHP6.0及以上版本通过与MySQL的紧密集成,为开发者提供了方便的工具来处理JSON数据。使用`JSON_CONTAINS`函数可以高效地查询JSON字段,同时结合框架的查询构造器和模型方法,让代码更加简洁易读。在实际...

    全国快递物流查询 阿里云 物流公司 mysql数据 与 json数据

    本文将详细探讨这个系统的核心组成部分——MySQL数据库和JSON数据格式。 首先,MySQL是一种广泛使用的开源关系型数据库管理系统,它在处理结构化数据方面表现出色。在物流查询系统中,MySQL用于存储大量的物流公司...

    mysql_json_JPAmysqljson_mysqljsonjpa_MYSQL_mysql支持json_

    MySQL数据库在近年来增加了对JSON数据类型的原生支持,这一特性极大地扩展了其在现代Web应用程序中的应用潜力。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以其易于人阅读和机器解析的特点,...

    MySQL.and.JSON

    MySQL 和 JSON 在现代数据处理中扮演着至关重要的角色。MySQL 是全球最受欢迎的关系型数据库管理系统(RDBMS),而 JSON(JavaScript Object Notation)是广泛使用的轻量级数据交换格式。两者结合,使得在数据库中...

    Mysql+Json+Android

    在这个场景中,我们关注的是MySQL数据库,JSON数据格式,以及它们在Android平台上的应用。这三者结合,构成了一个完整的数据处理和传输流程,对于Android应用开发者来说是必备的知识点。 **MySQL数据库** 是一个...

    MySQL操作之JSON数据类型操作详解

    MySQL从5.7.8版本开始引入了对JSON数据类型的内置支持,这使得在关系型数据库中处理非结构化数据成为可能。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于Web服务和应用程序之间的数据传输...

    可能是全网最齐全的全世界省市区划数据,mysql,json格式数据都有,带中英文国际化

    标题和描述中提到的数据集包含了全世界的省市区划信息,并且提供了多种格式,如MySQL数据库文件和JSON格式,还特别强调了中英文国际化处理。这表明这个数据集旨在服务于需要处理全球地理位置信息的项目,例如地图...

    spring-mybatis-mysql-json

    在MySQL中,JSON列可以存储任何有效的JSON文档,提供了对JSON数据的索引支持,以及一系列内置函数进行查询和更新操作。例如,`->`操作符用于访问JSON对象的属性,`JSON_EXTRACT`函数用于提取JSON对象的值,而`JSON_...

    Web开发-实现MySQL中存储JSON数据和将Excel数据导入到MySQL数据库.zip

    在本教程中,我们将探讨如何在MySQL中存储JSON数据以及如何利用Python将Excel数据导入到MySQL数据库。这两个主题对于数据驱动的Web应用来说尤其重要,因为它们涉及到数据的存储和处理。 首先,让我们深入了解在...

    MySql+JsonNet开发工具包.zip

    Json.NET库则提供了强大的功能来处理JSON数据。它可以将.NET对象序列化为JSON字符串,也可以从JSON字符串反序列化回.NET对象。这个工具包可能包括了如何使用Json.NET与MySQL数据库进行交互的示例代码,比如如何将...

    idea Java 解析json文件并导入mysql数据库

    在Java开发环境中,IntelliJ IDEA(简称Idea)是一个非常强大的集成开发工具,而处理JSON数据和与MySQL数据库交互是常见的任务。本教程将详细讲解如何在Idea中使用Java解析JSON文件,并将数据有效地导入到MySQL...

    Android中通过json向MySql中读写数据的方法

    Android 中通过 JSON 向 MySQL 中读写数据的方法是指在 Android 应用程序中使用 JSON(JavaScript Object Notation)格式将数据上传到 MySQL 数据库中,并从 MySQL 数据库中读取数据。这种方法可以实现 Android 应用...

    实现MySQL中存储JSON数据.rar

    在MySQL数据库中存储JSON数据是一种常见的需求,尤其是在处理半结构化数据时。JSON(JavaScript Object Notation)格式因其轻量级、易于阅读和编写的特点,被广泛用于数据交换。本教程将详细介绍如何在MySQL中存储和...

    国家区号mysql和json_中英文

    标题中的“国家区号mysql和json_中英文”指的是包含全球国家中英文名称及区号的数据,分别以MySQL数据库格式和JSON数据格式提供。这两种格式是数据存储和交换的常见方式,MySQL是一种关系型数据库管理系统,而JSON...

    实现MySQL中存储JSON数据.zip

    在MySQL数据库中存储JSON数据是现代应用程序中常见的需求,特别是在处理结构不固定或者需要灵活性的数据时。本资料包“实现MySQL中存储JSON数据.zip”主要关注如何利用Python框架与MySQL数据库进行交互,存储和检索...

Global site tag (gtag.js) - Google Analytics