JSON类型在日常应用开发中,用得很少,个人通常用于存储常常变化的配置参数。

它适用于什么业务场景,不好说。就好像许多年前读到的一篇文章,说有个国外公司利用ORACLE的CLOB/BLOB管理一些信息,好像还很成功的样子。

所以,客观地说,JSON的价值取决于工程师的能力和业务场景。

MYSQL8.0提供了许多的函数,详细的参阅官网的文档:

https://dev.mysql.com/doc/refman/8.0/en/json-functions.html

一、定义JSON字段

MYSQL提供了JSON类型字段,它至少某个程度上和字符类型的表现是一致的。

它和字符类型的主要区别在于:

  1. MYSQL会验证值的合法性。如果定义为varchar,text,那么MYSQL就不会去验证。
  2. 优化存储格式,以二进制的形式存储。读取的时候无需先转为json对象。所以读取更快

总结起来,还是直接定义为JSON类型更好。

至于具体业务场景中,是定义为JSON还是VARCHAR/TEXT之类的,需要看具体需要。

如果我们频繁存取JSON,那么通常还是建议使用JSON类型,而不是字符类型来存储JSON数据。

二、查找/获取值

这是最常用的函数类。

在很多情况下,我们并不使用MYSQL自身提供的JSON函数。

例如我需要把系统配置信息序列化到数据库,那么一般情况下,会直接通过面向对象的序列化功能,把对象序列化为JSON,在直接存入数据库。

但是常常会希望在SQL中获取JSON的某个值,而不希望把数据载入内存,再写代码解析。

MYSQL8关于查询的函数有许多;

JSON_CONTAINS(target, candidate[, path])  -- 类似exists 或者 having

JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)  --同上

JSON_EXTRACT(json_doc, path[, path] ...)  -- 读取某个键值

JSON_VALUE(json_doc, path)   -- 类似JSON_EXTRACT,但是比后者强,因为JSON_VALUE还可以把结果转为特定类型

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])   -- 通过键值获取键路径

... 略

本文只介绍JSON_EXTRACT和JSON_VALUE.

在开始介绍前,先介绍如何访问JSON对象的特定部分的键值,或者说如何书写键路径。

例如有JSON对象文本如下:

{
    "owner": "辛弃疾",
    "book": [
        {
            "name": "武德充沛的必要性",
            "price": 100
        },
        {
            "name": "哲学",
            "price": 90.5
        }
    ],
        "content":{
            "totalPage":456,
            "totalWords":400000
        }
}

这个路径必须以“$.”开头,后面就很好理解--和JAVA包路径一样,不同层级之间通过点号分隔。如果有数组,那么用"[]"表示,下标从0开始。

下面分别写两中路径语法例子:

  • 不带数组-$.k1.k2.k3....kn,其中n>=1
  • 带数组-$.k1.k2[i].k3....kn  ,其中n>=1,i>=0

三、返回结果集

上官方的表达式:

JSON_TABLE(
expr,
path COLUMNS (column_list)
) [AS] alias column_list:
column[, column][, ...] column:
name FOR ORDINALITY
| name type PATH string path [on_empty] [on_error]
| name type EXISTS PATH string path
| NESTED [PATH] path COLUMNS (column_list) on_empty:
{NULL | DEFAULT json_string | ERROR} ON EMPTY on_error:
{NULL | DEFAULT json_string | ERROR} ON ERROR

中括号,逗号以及竖线的含义请参阅mysql官方文档。表达式不难理解,只要看了例子。

但是如果涉及到嵌套等,就会有那么一点复杂了。

on empty,on error字句允许在没有或者发生错误的时候返回替代结果。

当至少在MYSQL8.0.X版本(截至20220623在8.0.29版本)中,这个功能还不是很完美:必须先关联才可以使用。

注:不关联也可以,不过对于我而言意义不大。

在我的一般业务场景中,我希望这样:

SELECT * FROM
json_table(json_extract(t_json.book,'$.book'),
"$[*]" COLUMNS(
NAME VARCHAR(60) path "$.name",
price DECIMAL(10,2) path "$.price"
)
) AS JJ;

但是这个不行的,会提示:

错误代码: 1109
Unknown table 't_json' in a table function argument

四、例子

数据库版本:centos8 mysql8.0.27 企业版(社区版)

建表T_JSON:

CREATE TABLE `t_json` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`book` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

插入数据到BOOK字段,内容如下(id略,脚本略):

    {
"book": [
{
"name": "中国的未来",
"price": 100
},
{
"name": "真理-数学",
"price": 100
}
],
"owner": "luzhifei",
"content": {
"totalPage": 945,
"totalWords": 9745556
}
}
------------------------
{
"book": [
{
"name": "武德充沛的必要性",
"price": 100
},
{
"name": "哲学",
"price": 90.5
}
],
"owner": "辛弃疾",
"content": {
"totalPage": 456,
"totalWords": 400000
}
}

1.JSON_VALUE

select JSON_VALUE(book,"$.content.totalPage" RETURNING decimal(10,2)) from t_json;
select JSON_VALUE(book,"$.content.totalPage") from t_json;

注:在8.0.20(windows)下,JSON_VALUE并不存在。

由于JSON_VALUE仅仅等价于(官方):

SELECT CAST(
JSON_UNQUOTE( JSON_EXTRACT(json_doc, path) )
AS type
);

所以,不使用JSON_VALUE,而使用替代脚本也可以。

2.JSON_EXTRACT

SELECT json_extract(book,'$.book') FROM t_json;

查询特定数组中某个key值:SELECT json_extract(book,'$.book[1].name') FROM t_json where id=3;

补充说明,可以使用->或者->>替代JSON_EXTRACT,具体例子见后文JSON_TABLE。

其中:

  1. ->   表示获取可能带有双引号的值
  2. ->> 获取不带双引号的值。通常我们使用这个。

3.JSON_TABLE

SELECT v.id,book->>"$.owner" AS author, book->"$.content.totalPage" AS totalPage,  t.name,t.price FROM t_json v,
json_table(json_extract(v.book,'$.book'),
  "$[*]" COLUMNS(
     NAME VARCHAR(60) path "$.name",
     price DECIMAL(10,2) path "$.price"
  )
) AS t;

SELECT v.id,json_extract(book,"$.owner") AS  author, json_extract(book,"$.content.totalPage") AS totalPage,     t.name,t.price FROM t_json v,
json_table(json_extract(v.book,'$.book'),
  "$[*]" COLUMNS(
     NAME VARCHAR(60) path "$.name",
     price DECIMAL(10,2) path "$.price"
  )
) AS t;

五、小结

JSON字段适用场景比较狭窄,尤其在一般应用开发领域,所以没有怎么关注。

JSON作为MYSQL一种类型补充,有了会方便点,没有也无所谓。

对于大部分程序员而言,JSON类型最大的价值在某些情况下可以于少写了一些代码,前提是你得恰当地适用。

如果业务场景中数据巨量,而且查询更新等都很频繁,不建议你适用这个数据类型,炫技除外!

于我而言,它的主要意义在于黑盒化信息,封装特定的业务,如果使用恰当的话。

例如某个配置又想添加一些属性,那么不需要对表格做任何修改,仅仅只需要修改下后台实现代码(通常情况)。如此,某种程度上有助于实现某种程度的开闭原则。

如果有需要大量使用非结构化数据和JSON的场景,可以考虑使用其它非关系数据库。

MYSQL8.0-JSON函数简单示例-JSON_EXTRACT|JSON_VALUE|JSON_TABLE的更多相关文章

  1. C++ 回调函数简单示例

    回调函数其实就是以函数指针做函数参数传递给另一个函数,在另一个函数执行的时候可以根据函数指针执行回调函数的代码.简单示例,便于理解,防止遗忘. #include <iostream> ty ...

  2. android json 解析 简单示例

    1 下面是一个简单的json 解析的demo,废话不多说,直接上代码 package com.sky.gallery; import java.io.ByteArrayOutputStream; im ...

  3. Python3基础 内嵌函数 简单示例

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  4. DB2函数简单示例

    DB2中的函数原理同其他编程语言中的函数,均为输入几个参数,同时返回一个值. 下面的例子演示一个寻找某一次考试中成绩最好的学生的姓名. 首先,我们新建一个表SCORE用于表示考试,并插入几条数据: D ...

  5. angular.fromJson(json)的简单示例

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. 【SqlServer】JSON函数

    1   概述 本篇文件将结合MSND简要分析Sqlserver中JSON函数,主要包括ISJSON,JSON_VALUE,JSON_MODIFY,JSON_QUERY. 2   具体内容 2.1  J ...

  7. ABAP分享一 弹出框函数的简单示例

    在开发中经常会使用到弹出框这个功能,在SAP中有很多函数可以实现类似的功能,这里介绍一个比较简单常用的函数  POPUP_TO_CONFIRM 下面是一个实现的简单示例: TABLES sscrfie ...

  8. windows下mysql8.0.x简单安装!

    1.官网下载mysql安装包并解压到自己喜欢的目录 2.在解压的目录下,添加my.ini配置文件,内容如下:[mysqld]# 设置3306端口port=3306# 设置mysql的安装目录 下面是我 ...

  9. MySQL8.0新特性实验1

    Server层,选项持久化 mysql> show variables like '%max_connections%';+------------------------+-------+| ...

  10. Mysql8.0.11简介,新特性

    MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...

随机推荐

  1. dotnet 使用 CsWin32 库简化 Win32 函数调用逻辑

    很多开发者,包括开发老司机们,在碰到需要调用 Win32 函数时,都有一个困扰,那就是我应该如何去调用.有两个主要的选项,第一就是自己写 PInvoke 代码,第二就是使用其他大佬给许多 Win32 ...

  2. WPF 如何获取有哪些 VisualBrush 用了某个控件

    我写了一个特殊的控件,我期望了解到有哪些 VisualBrush 捕获了此控件,或者说有哪些 VisualBrush 用了此控件的界面 本文的方法需要用到反射,需要使用 WPF 框架里面没有公开的字段 ...

  3. C语言的指针不能与数组之前的内存进行比较

    标准允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针进行比较,但是不允许与指向数组第一个元素之前的那个内存位置的指针进行比较. 案例一 #define DATAMAX 5 int ...

  4. R6_ES在互联网公司应用案例汇总参考

    Elasticsearch 是一个实时分布式搜索数据分析引擎,内部使用lucene做索引与搜索,能够解决常规和各种类型数据的存储及检索需求,典型的应用场景有:数据分析,站内搜索,ELK,电商等,主要特 ...

  5. 【爬虫+情感判定+饼图+Top10高频词+词云图】"王心凌"热门弹幕python舆情分析

    目录 一.背景介绍 二.代码讲解-爬虫部分 2.1 分析弹幕接口 2.2 讲解爬虫代码 三.代码讲解-情感分析部分 3.1 整体思路 3.2 情感分析打标 3.3 统计top10高频词 3.4 绘制词 ...

  6. 鸿蒙Blank

    Blank组件占剩余空间,类似占位组件一样

  7. 80x86汇编—汇编程序基本框架

    文章目录 First Program 指令系统 伪指令 数值表达式 程序框架解释 int 21 中断 通过一个基本框架解释各个指令和用处,方便复习.所以我认为最好的学习顺序就是先看一段完整的汇编代码程 ...

  8. java学习之旅(day.18)

    网络编程 概述 计算机网络:自己百度吧 网络编程的目的:传播交流信息.数据交换.通信 想要达到这个效果需要什么: 如何准确的定位网络上的一台主机 端口 定位到这个计算机上的某个资源 找到了这个主机,如 ...

  9. WPF绑定数据源到ListBox等selector的注意事项

    如果使用CollectionViewSource绑定到控件上,会导致默认选择第一项,而使用List,SelectedItem就默认为空. 要避免默认选择第一项,就要设置 ListBox.IsSynch ...

  10. Spring Boot中的 6 种API请求参数读取方式

    使用Spring Boot开发API的时候,读取请求参数是服务端编码中最基本的一项操作,Spring Boot中也提供了多种机制来满足不同的API设计要求. 接下来,就通过本文,为大家总结6种常用的请 ...