MySQL数据类型 - JSON数据类型 (2)

JSON值的规范化、合并和自动包装html

当一个字符串被解析并发现是一个有效的JSON文档时,它也会被规范化。这意味着,具备与稍后在文档中找到的键(从左到右)重复的键的成员将被丢弃。JSON_OBJECT()调用生成的对象值只包含第二个key1元素,由于该键名在以前值中出现过,以下所示:mysql

MySQL数据类型 - JSON数据类型 (2)

在JSON列中插入值时也会执行规范化,以下所示:算法

MySQL数据类型 - JSON数据类型 (2)
这种"最后一次重复的键获胜"的行为是由RFC 7159建议的,而且已由大多数JavaScript解析器实现。(Bug #86866, Bug #26369555)sql

在MySQL 8.0.3以前的版本中,与文档中先前找到的key重复的key成员将被丢弃。如下JSON_OBJECT()调用生成的对象值不包括第二个key1元素,由于该键名在前面出现过:
MySQL数据类型 - JSON数据类型 (2)json

在MySQL 8.0.3以前,在向JSON列中插入值时,也会执行"第一个重复键获胜"的规范化。数组

MySQL数据类型 - JSON数据类型 (2)

MySQL还会丢弃原始JSON文档中键、值或元素之间的多余空格,并在显示时在每一个逗号(,)或冒号(:)后保留(或在必要时插入)一个空格。这样作是为了提升可读性。并发

产生JSON值的MySQL函数老是返回规范化的值。ide

为了提升查找效率,MySQL还对JSON对象的键进行排序。应该意识到,此排序的结果可能会发生更改,而且不能保证在不一样版本之间保持一致。函数

合并JSON值spa

MySQL8.0.3(及更高版本)支持两种合并算法,由函数JSON_MERGE_PRESERVE()和JSON_MERGE_PATCH()实现。它们在处理重复键的方式上有所不一样:JSON_MERGE_PRESERVE()保留重复键的值,而JSON_MERGE_PATCH()将丢弃除最后一个值以外的全部值。接下来的几段将解释这两个函数如何处理JSON文档的不一样组合(即对象和数组)的合并。

注意

JSON_MERGE_PRESERVE()与早期版本的MySQL(在MySQL 8.0.3中重命名)中的JSON_MERGE()函数相同。在MySQL8.0中,JSON_MERGE()仍然以JSON_MERGE_PRESERVE()别名被支持,但已弃用,并可能在未来的版本中删除。

合并数组。在组合多个数组的上下文中,数组被合并成一个。JSON_MERGE_PRESERVE()经过将后面说起的数组链接到第一个数组的末尾来实现这一点。JSON_MERGE_PATCH()将每一个参数视为一个由单个元素组成的数组(所以其索引为0),而后应用"最后一个重复键获胜"逻辑来仅选择最后一个参数。您能够比较此查询显示的结果:
MySQL数据类型 - JSON数据类型 (2)

多个对象合并后生成一个对象。JSON_MERGE_PRESERVE()把数组中具备相同键的对象各惟一值合并;而后将该数组用做结果中该键的值。JSON_MERGE_PATCH()从左到右丢弃找到重复键的值,这样结果只包含该键的最后一个值。如下查询说明了重复键a的结果差别:
MySQL数据类型 - JSON数据类型 (2)

在须要数组值的上下文中使用非数组值是会自动包装的:该值由[和]字符包围以将其转换为数组。在下面的语句中,每一个参数都自动包装为一个数组([1],[2])。而后将这些值合并生成一个结果数组;与前两种状况同样,JSON_MERGE_PRESERVE()组合具备相同键的值,而JSON_MERGE_PATCH()将丢弃除最后一个外的全部重复键的值,以下所示:
MySQL数据类型 - JSON数据类型 (2)

数组和对象值的合并是经过将对象自动包装为一个数组,并经过合并值来合并数组,或者根据"最后的重复键获胜"原则(分别对应选择的合并函数是JSON_MERGE_PRESERVE()或JSON_MERGE_PATCH())合并数组,如本例所示:
MySQL数据类型 - JSON数据类型 (2)

搜索和修改JSON值

JSON路径表达式在JSON文档中选择一个值。

路径表达式指定操做文档位置,对于提取或修改JSON文档内容的函数很是有用。例如,如下查询从JSON文档中提取具备name键的成员的值:
MySQL数据类型 - JSON数据类型 (2)

路径语法使用前导的$字符来表示处理中的JSON文档,后面能够跟选择器(可选),这些选择器依次指示文档中更具体的部分:

●一个句点后跟一个键名,用给定的键命名对象中的成员。若是不带引号的键名称在路径表达式中不合法(例如,若是它包含空格),则必须用在双引号包含指定键名称。

● [N]附加到选择数组的路径后,表示在数组中位置N处的值。数组位置是以零开头的整数。若是路径未选择数组值,则路径[0]的计算结果与路径相同:

MySQL数据类型 - JSON数据类型 (2)

●[M to N]指定数组值的子集或范围,从位置M处的值开始,到位置N处的值结束。

支持用last做为最右边数组元素的索引的同义词。还支持数组元素的相对寻址。若是path没有选择数组值,path[last]的计算结果与path相同,如本节后面部分所示。

●路径能够包含*或**通配符:

■ .[*]计算JSON对象中全部成员的值。

■ [*]计算JSON数组中全部元素的值。

■ prefix**suffix计算以prefix开头、以suffix结束的全部路径。

● 文档中不存在的路径(计算结果为不存在的数据)计算结果为NULL。

让$引用包含三个元素的JSON数组:
MySQL数据类型 - JSON数据类型 (2)

而后:

● $[0]的计算结果为3。

● $[1]的计算结果为{"a": [5, 6], "b": 10}。

● $[2]的计算结果为[99, 100]。

● $[3]的计算结果为NULL(它引用第四个数组元素,它不存在)。

因为$[1]和$[2]的计算结果为非标量值,所以能够用更具体的路径表达式对它们选择嵌套的值。示例:

●$[1].a的计算结果为[5, 6]。

●$[1].a[1]的计算结果为6。

●$[1].b的值为10。

●$[2][0]的计算结果为99。

如前所述,若是未加引号的键名称在路径表达式中不合法,则必须用引号将键引发。让$来引用此值:
MySQL数据类型 - JSON数据类型 (2)

两个键都包含空格,必须用引号引用:

●$."a fish"的计算结果是shark。

●$."a bird"的计算结果是sparrow。

使用通配符的路径计算的数组能够包含多个值:

MySQL数据类型 - JSON数据类型 (2)

在如下示例中,路径$**.b计算为多个路径($.a.b和$.c.b),并生成匹配路径值的数组:

MySQL数据类型 - JSON数据类型 (2)

JSON数组区间。能够使用带有to关键字的区间来指定JSON数组的子集。例如,$[1 to 3]包括数组的第2、第三和第四个元素,以下所示:

MySQL数据类型 - JSON数据类型 (2)

语法是 M to N,其中M和N分别是JSON数组中一系列元素的第一个和最后一个索引。N必须大于M;M必须大于或等于0。数组元素以0开头编制索引。

能够在支持通配符的上下文中使用区间。

官方文档地址:
https://dev.mysql.com/doc/refman/8.0/en/json.html

相关文章
相关标签/搜索