译者:QunFanYi.com 英文原文:JSON enhancements https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html 对MySQL的JSON功能进行了以下增强或添加:
译者:QunFanYi.com 英文原文:JSON enhancements https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html 对MySQL的JSON功能进行了以下增强或添加:
添加了 →
(内联路径)运算符,这等价于在JSON_EXTRACT()的结果上调用JSON_UNQUOTE()。
这是对MySQL 5.7中引入的列路径操作符→的改进;col→“$.path”等效于JSON_UNQUOTE(col→“$.path”)。可以用JSON_UNQUOTE(JSON_EXTRACT())的地方都可以使用内联路径操作符,例如SELECT列列表、WHERE和HAVING子句以及ORDER BY和GROUP BY子句。有关更多信息,请参阅操作符的描述以及 JSON路径语法。
添加了两个JSON聚合函数JSON_ARRAYAGG()和JSON_OBJECTAGG()。JSON_ARRAYAGG() 使用列或表达式作为参数,并将结果聚合为单个JSON数组。表达式可以计算任何MySQL数据类型;不一定是JSON值。JSON_OBJECTAGG()接受两个列或表达式,并将它们解释为键和值;它将结果作为单个JSON对象返回。有关更多信息和示例,请参阅第12.20节“聚合(GROUP BY)函数”。
添加了JSON实用程序函数JSON_PRETTY(),该函数以易于读取的格式输出现有JSON值;每个JSON对象成员或数组值都打印在单独的行上,并且子对象或数组相对于其父对象多使用2个空格。
这个函数还处理可以解析为JSON值的字符串。
更多信息和示例,请参阅第12.17.7节“JSON实用函数”。
当使用ORDER BY对查询中的JSON值进行排序时,每个值现在由排序键的可变长度部分表示,而不是固定1K大小的部分。在许多情况下,这可以减少过度的使用;例如,标量INT甚至BIGINT值实际上只需要很少的字节,因此该空间的其余部分(高达90%或更多)由填充占用。此更改比较有利性能提升:
排序缓冲区空间现在被更有效地使用,因此文件不需要像使用固定长度排序键那样早或频繁地刷新到磁盘。这意味着可以在内存中对更多的数据进行排序,从而避免不必要的磁盘访问。
短键可以比长键更快地进行比较,从而在性能上显著提高。对于完全在内存中执行的排序以及需要向磁盘写入和从磁盘读取的排序,这是正确的。
在MySQL 8.0.2中增加了对JSON列值的局部就地更新的支持,这比完全删除现有JSON值并在其位置写入新JSON值更高效,如之前在更新任何JSON列时所做的那样。为了应用这种优化,必须使用JSON_SET()、JSON_REPLACE()或JSON_REMOVE()应用更新。无法向正在更新的JSON文档添加新元素;文档中的值不能比更新之前占用更多的空间。有关需求的详细讨论,请参阅JSON值的部分更新。
JSON文档的部分更新可以写入二进制日志,比记录完整的JSON文档占用更少的空间。当使用基于语句的复制时,总是记录部分更新。要使用基于行的复制,必须首先设置binlog_row_value_.=PARTIAL_JSON;有关更多信息,请参阅此变量的描述。
添加了JSON实用程序函数JSON_STORAGE_SIZE()和JSON_STORAGE_FREE()。JSON_STORAGE_SIZE()返回在任何部分更新之前用于JSON文档的二进制表示的字节存储空间(参见前一项)。JSON_STORAGE_FREE()显示JSON类型的表列在使用JSON_SET()或JSON_REPLACE()部分更新之后剩余的空间量;如果新值的二进制表示小于前一个值的二进制表示则大于零。
每个函数还接受JSON文档的有效字符串表示。对于这样的值,JSON_STORAGE_SIZE()返回其二进制表示在转换为JSON文档之后使用的空间。对于包含JSON文档的字符串表示的变量,JSON_STORAGE_FREE()返回零。如果函数的(非空)参数不能被解析为有效的JSON文档,则这两个函数都会产生错误;如果参数是NULL,则这两个函数都会产生NULL。
有关更多信息和示例,请参阅第12.17.7节“JSON实用程序函数”。
JSON_STORAGE_SIZE()和JSON_STORAGE_FREE()在MySQL 8.0.2中实现。
在MySQL 8.0.2中增加了对范围(如XPath表达式中的$[1至5])的支持。在这个版本中还添加了对最后一个关键字和相对寻址的支持,使得$[last]总是选择数组中的最后一个(编号最高的)元素,而$[last-1]总是选择最后一个元素。last以及使用它的表达式也可以包含在范围定义中;例如,$[last-2到last-1]返回最后两个元素,但是从数组返回一个元素。See Searching and Modifying JSON Values, for additional information and examples.
添加了JSON合并功能,以符合RFC 7396。JSON_MERGE_PATCH()用于两个JSON对象时,将它们合并为单个JSON对象,该JSON对象具有以下集合的联合:
第二对象中没有具有相同密钥的成员的第一对象的每个成员。
第二对象的每个成员,其中在第一对象中没有具有相同键的成员,并且其值不是JSON空文本。
每个成员都有一个存在于两个对象中的键,并且在第二个对象中的值不是JSON空文本。
作为这项工作的一部分,JSON_MERGE()函数被重命名为JSON_MERGE_PRESERVE()。JSON_MERGE()仍然被识别为MySQL 8.0中JSON_MERGE_PRESERVE()的别名,但是现在被弃用,并且在MySQL的未来版本中被删除。
有关更多信息和示例,请参阅第12.17.4节“修改JSON值的函数”。
规范化重复 key 的处理 实现了“最后一个重复 key 被采用” ,与RFC 7159和大多数JavaScript解析器一致。这里显示了这种行为的示例,其中仅保留具有重复 key x的最右边的成员:
mysql> SELECT JSON_OBJECT('x', '32', 'y', '[true, false]',
> 'x', '"abc"', 'x', '100') AS Result;
+------------------------------------+
| Result |
+------------------------------------+
| {"x": "100", "y": "[true, false]"} |
+------------------------------------+
1 row in set (0.00 sec)
插入MySQL JSON列的值也以这种方式标准化,如本示例所示:
mysql> CREATE TABLE t1 (c1 JSON);
mysql> INSERT INTO t1 VALUES ('{"x": 17, "x": "red", "x": [3, 5, 7]}');
mysql> SELECT c1 FROM t1;
+------------------+
| c1 |
+------------------+
| {"x": [3, 5, 7]} |
+------------------+
与MySQL以前的版本相比,这是一个不兼容的改变,在这种情况下使用了“采用第一个重复 key”算法。
有关更多信息和示例,请参阅JSON值的规范化、合并和自动包装。
在MySQL 8.0.4中添加了JSON_TABLE()函数。此函数接受JSON数据并作为具有指定列的关系表返回。
此函数具有语法JSON_TABLE(expr,path COLUMNS column_list)[AS]别名,其中expr是返回JSON数据的表达式,path是应用于源的JSON路径,column_list是列定义的列表。这里显示了一个示例:
mysql> SELECT *
-> FROM
-> JSON_TABLE(
-> '[{"a":3,"b":"0"},{"a":"3","b":"1"},{"a":2,"b":1},{"a":0},{"b":[1,2]}]',
-> "$[*]" COLUMNS(
-> rowid FOR ORDINALITY,
->
-> xa INT EXISTS PATH "$.a",
-> xb INT EXISTS PATH "$.b",
->
-> sa VARCHAR(100) PATH "$.a",
-> sb VARCHAR(100) PATH "$.b",
->
-> ja JSON PATH "$.a",
-> jb JSON PATH "$.b"
-> )
-> ) AS jt1;
+-------+------+------+------+------+------+--------+
| rowid | xa | xb | sa | sb | ja | jb |
+-------+------+------+------+------+------+--------+
| 1 | 1 | 1 | 3 | 0 | 3 | "0" |
| 2 | 1 | 1 | 3 | 1 | "3" | "1" |
| 3 | 1 | 1 | 2 | 1 | 2 | 1 |
| 4 | 1 | 0 | 0 | NULL | 0 | NULL |
| 5 | 0 | 1 | NULL | NULL | NULL | [1, 2] |
+-------+------+------+------+------+------+--------+
JSON源表达式可以是产生有效JSON文档的任何表达式,包括JSON文本、表列或返回JSON的函数调用,例如JSON_EXTRACT(t1,data,'$.post..')。有关更多信息,请参阅第12.17.6节“ JSON表函数 ”。