MYSQL 5.7 中的原生 JSON 支持:MYSQL 中 JSON 数据类型的优点和缺点是什么?

2023-12-26

MySQL 5.7 中用于存储的新数据类型MySQL 中的 JSON 数据 http://dev.mysql.com/doc/refman/5.7/en/json.html表已 添加。显然这对MySQL来说是一个巨大的改变。他们列出了一些好处

文件验证- 只有有效的 JSON 文档才能存储在 JSON 列,以便您自动验证数据。

高效接入- 更重要的是,当您将 JSON 文档存储在 JSON 列中时,它不会存储为纯文本值。相反,它被存储 采用优化的二进制格式,可以更快地访问对象 成员和数组元素。

表现- 改进您的查询 通过对 JSON 列中的值创建索引来提高性能。 这可以通过虚拟列上的“功能索引”来实现。

方便- JSON 列的附加内联语法使其 将文档查询集成到 SQL 中是非常自然的。为了 示例(features.feature 是 JSON 列):SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;

哇 !它们包含一些很棒的功能。现在操作数据变得更加容易。现在可以在列中存储更复杂的数据。 所以 MySQL 现在加入了 NoSQL。

现在我可以想象对 JSON 数据的查询类似于

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN 
( 
SELECT JSON_EXTRACT(data,"$.inverted") 
FROM t1 | {"series": 3, "inverted": 8} 
WHERE JSON_EXTRACT(data,"$.inverted")<4 );

那么我可以在几个 json 列中存储巨大的小关系吗?好吗?它是否打破了常态化。如果这是可能的,那么我想它会像 MySQL 列中的 NoSQL 一样。我真的很想了解更多有关此功能的信息。 MySQL JSON 数据类型的优缺点。


SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

在这样的表达式或函数中使用列会破坏查询使用索引来帮助优化查询的任何机会。上面显示的查询被迫进行表扫描。

关于“高效访问”的说法具有误导性。这意味着在查询检查包含 JSON 文档的行后,它可以提取字段,而无需解析 JSON 语法的文本。但仍然需要表扫描来搜索行。换句话说,查询必须检查每一行。

打个比方,如果我在电话簿中搜索名字为“Bill”的人,我仍然需要阅读电话簿中的每一页,即使名字已突出显示,以便更快地找到他们。

MySQL 5.7允许您在表中定义虚拟列,然后在虚拟列上创建索引。

ALTER TABLE t1
  ADD COLUMN series AS (JSON_EXTRACT(data, '$.series')),
  ADD INDEX (series);

然后,如果您查询虚拟列,它可以使用索引并避免表扫描。

SELECT * FROM t1
WHERE series IN ...

这很好,但它有点忽略了使用 JSON 的意义。使用 JSON 的吸引力在于它允许您添加新属性而无需执行 ALTER TABLE。但事实证明,如果您想借助索引搜索 JSON 字段,则无论如何都必须定义一个额外的(虚拟)列。

但您不必为其定义虚拟列和索引everyJSON 文档中的字段 - 仅那些您想要搜索或排序的字段。 JSON 中可能还有其他属性,您只需在选择列表中提取这些属性,如下所示:

SELECT JSON_EXTRACT(data, '$.series') AS series FROM t1
WHERE <other conditions>

我通常会说这是在 MySQL 中使用 JSON 的最佳方式。仅在选择列表中。

当您引用其他子句(JOIN、WHERE、GROUP BY、HAVING、ORDER BY)中的列时,使用常规列(而不是 JSON 文档中的字段)会更有效。

我做了一个演讲,叫做如何在 MySQL 中错误地使用 JSON https://www.slideshare.net/billkarwin/how-to-use-json-in-mysql-wrong在 2018 年 4 月的 Percona Live 会议上。我将在秋季更新并重复在 Oracle Code One 上的演讲。

JSON 还有其他问题。例如,在我的测试中,与存储相同数据的传统列相比,JSON 文档需要的存储空间是传统列的 2-3 倍。

MySQL 正在积极推广其新的 JSON 功能,主要是为了阻止人们迁移到 MongoDB。但像 MongoDB 这样的面向文档的数据存储从根本上来说是一种非关系型数据组织方式。它与关系型不同。我并不是说一个比另一个更好,它只是一种不同的技术,适合不同类型的查询。

当 JSON 使您的查询更加高效时,您应该选择使用 JSON。

不要仅仅因为一项技术新颖或为了时尚而选择它。


编辑:如果您的 WHERE 子句使用与虚拟列定义完全相同的表达式,则 MySQL 中的虚拟列实现应该使用索引。也就是说,下面的should使用虚拟列上的索引,因为虚拟列已定义AS (JSON_EXTRACT(data,"$.series"))

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

但我通过测试此功能发现,如果表达式是 JSON 提取函数,则由于某种原因它不起作用。它适用于其他类型的表达式,但不适用于 JSON 函数。更新:据报道,这最终在 MySQL 5.7.33 中有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MYSQL 5.7 中的原生 JSON 支持:MYSQL 中 JSON 数据类型的优点和缺点是什么? 的相关文章

  • HTML 和 BeautifulSoup:当结构事先不知道时如何迭代解析?

    我从一个简单的 HTML 结构开始 如下所示 感谢 alecxe 的帮助 我能够创建这个 JSON 字典 u Outer List u Inner List u info 1 u info 2 u info 3 使用他的代码 from bs
  • PHP 中的依赖注入

    我一直在研究依赖注入 我是在关注某件事还是完全没有关注 代码是好是坏 依赖注入与否 下面的代码是CMS系统的基础 现在有一个名为 page details 的表 其中存储了所有网页 目录 文件结构 htaccess index php cl
  • 一个大连接或多个查询哪个提供更好的性能?

    我有一个名为订单的表 订单上的一列是 customer id我有一个名为 customers 的表 有 10 个字段 给定两个选项 如果我想构建订单对象数组并嵌入订单对象中的是客户对象 我有两个选择 选项1 A 首先查询订单表 b 循环遍历
  • mysql中的保存点提交回滚[重复]

    这个问题在这里已经有答案了 我们如何在mysql中使用提交 回滚和保存点 CREATE TABLE t test id INT NOT NULL PRIMARY KEY ENGINE InnoDB START TRANSACTION INS
  • dump() 缺少 1 个必需的位置参数:python json 中的“fp”

    我正在尝试美化 json 格式 但收到此错误 import requests as tt from bs4 import BeautifulSoup import json get url tt get https in pinterest
  • 如何将react-native与php一起使用并获取返回数据始终为空

    我的回报始终为空 我似乎无法让它发挥作用 我如何将react native与php一起使用并获取json 任何人都可以帮忙吗 PHP myArray array myArray lat POST lat myArray lng POST l
  • SQL 中的 JOIN 成本有多高?和/或,性能和标准化之间的权衡是什么?

    我发现了一个类似的线程 但它并没有真正抓住我想要问的本质 所以我创建了一个新线程 我知道规范化和性能之间存在权衡 我想知道划定这条线的最佳实践是什么 在我的特定情况下 我有一个消息传递系统 它具有三个不同的表 messages thread
  • JsPdf 库无法读取 PDF 中的阿拉伯语

    在 pdf 中显示阿拉伯值的代码不起作用 它向我展示了一些我无法理解的奇怪语言 var sm nature name nature1 ar 1 name nature2 ar 2 name nature3 ar 3 name nature4
  • 关于ORA 21000

    我正在与 ORA 21000 作斗争 上面写着ORA 21000 raise application error 的错误号参数 3739 超出范围 此错误间歇性出现 我不知道为什么会发生这种情况 早些时候这工作得很好 但是从 Solaris
  • 使用 JSONPath 按名称过滤 json 属性

    我想选择属性名称中具有特定匹配项的所有元素 例如 此 json 中名称以 pass 开头的所有属性 firstName John lastName doe age 50 password 1234 phoneNumbers type iPh
  • 将字符串替换为 jq

    我有以下文件file txt a a b a time 20210210T10 10 00 a b b b time 20210210T11 10 00 我用以下方法提取值bash命令jq 我在海量 100g 文件上使用此命令 jq r a
  • 在 MySQL 中对连续值进行分组并向这些组添加 id

    我有一个简单的表 我需要确定四行的组 这些组不是连续的 但每行的每一行的值都有 1 例如 language id C 16 C 17 Java 18 Python 19 HTML 65 JavaScript 66 PHP 67 Perl 6
  • 如何确定c3p0 max_statements

    我想知道如何正确确定 c3p0 max statements 使用什么值 我经历过一些缓存死锁 这似乎指向我的 max statements 配置 基于我读过的所有 SO 问答 我正在使用 mysql 当我进行一些有 4 个活动线程的多线程
  • 环回:原子读取和更新

    有没有办法在环回中实现类似的东西 LOCK READ INCREMENT UNLOCK 我想将计数器保留为数据库值 每个键都是一个计数器 或一个设置 并且它们不应该同时访问我的多个请求 此外 这也应该适用于本地请求 无 RemoteHook
  • 如何调试 MySQL 存储过程?

    我当前的调试存储过程的过程非常简单 我创建一个名为 debug 的表 在存储过程运行时从其中插入变量值 这允许我查看脚本中给定点的任何变量的值 但是有没有更好的方法来调试 MySQL 存储过程 下列debug msg可以调用过程来简单地将调
  • 如何将两个django模型(表)合并为一个模型(表)

    我想合并两个 django 模型并创建单个模型 我们假设 我有第一个表表 A 其中包含一些列和数据 Table A col1 col2 col3 col4 x1 x2 x3 x4 y1 y2 y3 y4 我还有另一个表 Table B 其中
  • 如何获取与值匹配或存在于另一个表中的记录?

    我试图弄清楚在这种情况下如何获取所有任务 其中两个字段等于某个值或者它们存在于另一个表中 这是查询 SELECT TASKS task id TASKS task title TASKS task description TASKS tas
  • Spring boot JDBC无法连接docker容器中的mysql

    我正在尝试在两个单独的 docker 容器中运行 spring boot 应用程序 作为简单的 REST api 和 mysql 服务器 但是 我无法在 Spring 应用程序中获取 jdbc 连接来连接 mysql 它们都是独立工作的 当
  • 使用 Symfony 表单上传多个文件

    UPDATED在我的 Symfony 项目中 我能够上传单个图像 现在我正在尝试上传多个图像 class ImageFile extends AbstractType param FormBuilderInterface builder p
  • JsonNode findValue 不搜索子节点

    我有一个结构如下的资源 activity activity type Like activity id 123456 object id product id reference activity activity type Rating

随机推荐

  • Vimscript:列出的缓冲区数量

    在我的 vim 脚本中 我需要获取所有被视为列出 可列出的缓冲区的计数 即所有执行此操作的缓冲区 not具有未列出的 u 属性 推导该值的推荐方法是什么 你可以使用bufnr 获取最后一个缓冲区的编号 然后创建一个 列出从 1 到该数字并过
  • 使用指针嵌套 std::map

    我在地图内使用地图 并希望访问第二个地图中的特定成员 std map
  • 在Web Api中使用Postman授权属性认证

    我正在使用 RESTful 服务 并发现 Postman 是 GET POST 和测试 API 的最佳插件之一 我在邮递员中找到基本身份验证 无身份验证 DIgest Auth OAuth AWS 如何测试授权控制器和方法 我知道授权属性检
  • 为什么这个SQL语句很慢?

    我有一个包含大约 100 万条记录的表 运行 SQL Server 2008 Web 我有一个搜索例程 尝试匹配产品代码和产品描述 但在某些情况下 速度非常慢 下面是 精简的 sql 语句 WITH AllProducts AS SELEC
  • 当进行相同的 PDO 查询(参数不断变化)时,我是每次都调用prepare(),还是只调用一次?

    我正在尝试学习如何使用 PDO 并且需要帮助理解一些内容 我一直读到使用 PDO 的最大好处之一是它比mysql 当一遍又一遍地进行类似的查询时 我需要进行一个完全相同的查询 只是绑定参数每次都会改变 但查询的结构是相同的 所以 这是我的问
  • 如何覆盖 Riverpod StateNotifier 的状态以进行测试

    我想覆盖我的StateNotifierProvider手动声明以进行测试 可以使用以下方式覆盖提供者ProviderContainer or ProviderScope 但它只提供了覆盖通知者的选项 而不是状态 我的问题是我应该如何覆盖状态
  • Jquery图像叠加?

    我希望使用 jquery 将右上角的图像覆盖在另一张图像上 基本上 当用户的鼠标悬停在图像上方时 我希望第二个图像出现在右上角的另一张图像上方 然后当用户停止悬停在图像上时消失 我如何用 Jquery 实现这一点 Senad 是很正确的 你
  • 父进程如何通过调用_exit的子进程的wait来获取终止状态

    我已阅读以下声明 给 exit 的 status 参数定义了终止状态 该进程 当该进程的父进程可用时 该进程可用 调用 wait 进程总是由 exit 成功终止 即 出口 一去不复返 Question If exit不返回 父进程如何获取终
  • ASP.Net MVC jQuery AJAX 路由问题

    我的页面是domain com home details 1 在我的 jQuery AJAX 调用中 我有以下内容 但是当它进行该调用时 它会调用domain com home details home getdata 我该怎么做才能让它得
  • React Native:无法导入 csv 文件

    我有一个csv文件位于 src data文件夹 我希望导入它以便能够传递到帕帕帕斯库被解析为JSON图书馆 这是我用来执行此操作的脚本 import Papa from papaparse import file from src data
  • Micronaut-Core:如何创建动态端点

    简单的问题 是否可以创建端点而无需 Endpoint 我想通过文件并根据其上下文的内容创建相当动态的端点 Thanks 更新一下我的想法 我想创建类似插件系统的东西 以使我的应用程序对于维护和未来功能更具可扩展性 值得一提的是 我正在使用
  • 如何将pyspark数据帧写入HDFS,然后如何将其读回数据帧?

    我有一个非常大的 pyspark 数据框 所以我想对其子集进行预处理 然后将它们存储到hdfs 后来我想把它们全部读完并合并在一起 谢谢 将 DataFrame 写入 HDFS Spark 1 6 df write save target
  • 在新的 stdClass 中声明匿名函数

    只是想知道为什么这样的东西不起作用 public function address name if isset this gt addresses name address new stdClass address gt city func
  • 底层连接已关闭:发送时发生意外错误。--- NuGet

    在尝试恢复 nuget 包时 我得到以下信息 错误 1 基础连接已关闭 发送时发生意外错误 错误 2 底层连接已关闭 无法建立 SSL TLS 安全通道的信任关系 错误 3 命令 D root nuget NuGet exe install
  • 如何用猫鼬进行分页

    我想在我的收藏中添加分页功能 如何在单个查询中找到具有 开始 和 限制 位置的文档并获取文档总数 您无法在一次查询中获得两个结果 你能做的最好的事情就是用一只 Mongoose 让它们都得到Query http mongoosejs com
  • max_user_connections 或超出 ip 连接限制 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我收到以下 PHP 错误消息 Use
  • OpenCV背景减法学习率不能改变

    我希望训练一个 50 帧的背景区域 并使用这个预训练的模型进行背景减除 模型在训练后停止更新 这是我的代码 import cv2 print This program is for background subtraction with p
  • 每五个单词后分割字符串

    我想每五个单词后分割一个字符串 Example 这里有一些东西要输入 这是示例文本 Output There is something to type here This is an example text 如何使用preg split
  • Cordova android 仿真 - 错误:无法读取 null 的属性“semver”

    尝试使用 cordova 模拟 Android 应用程序 但收到此错误消息 构建了以下 apk Users jnj cordova hello platforms android build outputs apk android debu
  • MYSQL 5.7 中的原生 JSON 支持:MYSQL 中 JSON 数据类型的优点和缺点是什么?

    MySQL 5 7 中用于存储的新数据类型MySQL 中的 JSON 数据 http dev mysql com doc refman 5 7 en json html表已 添加 显然这对MySQL来说是一个巨大的改变 他们列出了一些好处