MySQL supports a native MySQL支持RFC 7159定义的原生JSON
data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. JSON
数据类型,该类型支持对JSON(JavaScript对象表示法)文档中的数据的有效访问。The 与在字符串列中存储JSON
data type provides these advantages over storing JSON-format strings in a string column:JSON
格式的字符串相比,JSON数据类型具有以下优势:
Automatic validation of JSON documents stored in 自动验证存储在JSON
columns. JSON
列中的JSON文档。Invalid documents produce an error.无效文档会产生错误。
Optimized storage format. 优化的存储格式。JSON documents stored in 存储在JSON
columns are converted to an internal format that permits quick read access to document elements. JSON
列中的JSON文档被转换为允许对文档元素进行快速读取访问的内部格式。When the server later must read a JSON value stored in this binary format, the value need not be parsed from a text representation. 当服务器稍后必须读取以这种二进制格式存储的JSON值时,不需要从文本表示中解析该值。The binary format is structured to enable the server to look up subobjects or nested values directly by key or array index without reading all values before or after them in the document.二进制格式的结构使服务器能够直接按键或数组索引查找子对象或嵌套值,而不必读取文档中它们之前或之后的所有值。
MySQL 8.0 also supports the JSON Merge Patch format defined in RFC 7396, using the MySQL 8.0还支持RFC 7396定义的JSON合并补丁格式,使用JSON_MERGE_PATCH()
function. JSON_Merge_Patch()
函数。See the description of this function, as well as Normalization, Merging, and Autowrapping of JSON Values, for examples and further information.有关示例和更多信息,请参阅此函数的描述,以及JSON值的规范化、合并和自动折行。
This discussion uses 本讨论使用单一类型的JSON
in monotype to indicate specifically the JSON data type and “JSON” in regular font to indicate JSON data in general.JSON
来具体表示JSON数据类型,使用常规字体的“JSON”来表示JSON数据。
The space required to store a 存储JSON
document is roughly the same as for LONGBLOB
or LONGTEXT
; see Section 11.7, “Data Type Storage Requirements”, for more information. JSON
文档所需的空间与LONGBLOB
或LONGTEXT
大致相同;有关更多信息,请参阅第11.7节,“数据类型存储要求”。It is important to keep in mind that the size of any JSON document stored in a 重要的是要记住,存储在JSON
column is limited to the value of the max_allowed_packet
system variable. JSON
列中的任何JSON文档的大小都限制为max_allowed_packet
系统变量的值。(When the server is manipulating a JSON value internally in memory, it can be larger than this; the limit applies when the server stores it.) (当服务器在内存内部操作一个JSON值时,它可以大于这个值;该限制在服务器存储时适用。)You can obtain the amount of space required to store a JSON document using the 您可以使用JSON_STORAGE_SIZE()
function; note that for a JSON
column, the storage size—and thus the value returned by this function—is that used by the column prior to any partial updates that may have been performed on it (see the discussion of the JSON partial update optimization later in this section).JSON_STORAGE_SIZE()
函数获取存储JSON文档所需的空间量;请注意,对于JSON
列,存储大小以及由此函数返回的值是该列在对其执行任何部分更新之前所使用的值(请参阅本节后面对JSON部分更新优化的讨论)。
Prior to MySQL 8.0.13, a 在MySQL8.0.13之前,JSON
column cannot have a non-NULL
default value.JSON
列不能有非NULL
的默认值。
Along with the 除了JSON
data type, a set of SQL functions is available to enable operations on JSON values, such as creation, manipulation, and searching. JSON
数据类型之外,还提供了一组SQL函数来支持对JSON值的操作,例如创建、操作和搜索。The following discussion shows examples of these operations. 下面的讨论展示了这些操作的示例。For details about individual functions, see Section 12.18, “JSON Functions”.有关单个函数的详细信息,请参阅第12.18节,“JSON函数”。
A set of spatial functions for operating on GeoJSON values is also available. 还提供了一组用于操作GeoJSON值的空间函数。See Section 12.17.11, “Spatial GeoJSON Functions”.参见阅第12.17.11节,“空间GeoJSON函数”。
JSON
columns, like columns of other binary types, are not indexed directly; instead, you can create an index on a generated column that extracts a scalar value from the JSON
column. JSON
列与其他二进制类型的列一样,不直接编制索引;相反,可以在生成的列上创建索引,从JSON
列中提取标量值。See Indexing a Generated Column to Provide a JSON Column Index, for a detailed example.有关详细示例,请参阅索引生成的列以提供JSON列索引。
The MySQL optimizer also looks for compatible indexes on virtual columns that match JSON expressions.MySQL优化器还会在与JSON表达式匹配的虚拟列上查找兼容的索引。
In MySQL 8.0.17 and later, the 在MySQL 8.0.17及更高版本中,InnoDB
storage engine supports multi-valued indexes on JSON arrays. InnoDB
存储引擎支持JSON数组上的多值索引。See Multi-Valued Indexes.请参阅多值索引。
MySQL NDB Cluster 8.0 supports MySQL NDB Cluster 8.0支持JSON
columns and MySQL JSON functions, including creation of an index on a column generated from a JSON
column as a workaround for being unable to index a JSON
column. JSON
列和MySQL JSON函数,包括在JSON
列生成的列上创建索引,作为无法索引JSON
列的解决方法。A maximum of 3 每个JSON
columns per NDB
table is supported.NDB
表最多支持3个JSON列。
In MySQL 8.0, the optimizer can perform a partial, in-place update of a 在MySQL 8.0中,优化器可以执行JSON
column instead of removing the old document and writing the new document in its entirety to the column. JSON
列的局部就地更新,而不是删除旧文档并将新文档全部写入该列。This optimization can be performed for an update that meets the following conditions:可以对满足以下条件的更新执行此优化:
The column being updated was declared as 正在更新的列被声明为JSON
.JSON
。
The UPDATE
statement uses any of the three functions JSON_SET()
, JSON_REPLACE()
, or JSON_REMOVE()
to update the column. UPDATE
语句使用三个函数JSON_SET()
、JSON_REPLACE()
或JSON_REMOVE()
中的任意一个来更新列。A direct assignment of the column value (for example, 列值的直接赋值(例如,UPDATE mytable SET jcol = '{"a": 10, "b": 25}'
) cannot be performed as a partial update.UPDATE mytable SET jcol = '{"a": 10, "b": 25}'
)不能作为部分更新执行。
Updates of multiple 在一个JSON
columns in a single UPDATE
statement can be optimized in this fashion; MySQL can perform partial updates of only those columns whose values are updated using the three functions just listed.UPDATE
语句中更新多个JSON
列可以用这种方式进行优化;MySQL只能对那些使用刚刚列出的三个函数更新其值的列执行部分更新。
The input column and the target column must be the same column; a statement such as 输入列和目标列必须是同一列;诸如UPDATE mytable SET jcol1 = JSON_SET(jcol2, '$.a', 100)
cannot be performed as a partial update.UPDATE mytable SET jcol1 = JSON_SET(jcol2, '$.a', 100)
之类的语句不能作为部分更新执行。
The update can use nested calls to any of the functions listed in the previous item, in any combination, as long as the input and target columns are the same.只要输入列和目标列相同,更新可以以任何组合使用对上一项中列出的任何函数的嵌套调用。
All changes replace existing array or object values with new ones, and do not add any new elements to the parent object or array.所有更改都将现有数组或对象值替换为新值,并且不向父对象或数组添加任何新元素。
The value being replaced must be at least as large as the replacement value. 被替换的值必须至少与替换值一样大。In other words, the new value cannot be any larger than the old one.换句话说,新值不能大于旧值。
A possible exception to this requirement occurs when a previous partial update has left sufficient space for the larger value. 当以前的部分更新为较大的值留下了足够的空间时,可能会出现此要求的例外情况。You can use the function 您可以使用函数JSON_STORAGE_FREE()
see how much space has been freed by any partial updates of a JSON
column.JSON_STORAGE_FREE()
查看JSON列的任何部分更新释放了多少空间。
Such partial updates can be written to the binary log using a compact format that saves space; this can be enabled by setting the 这样的部分更新可以使用节省空间的紧凑格式写入二进制日志;这可以通过将binlog_row_value_options
system variable to PARTIAL_JSON
. binlog_row_value_options
系统变量设置为PARTIAL_JSON
来启用。See the description of this variable for more information.有关详细信息,请参见此变量的说明。
The next few sections provide basic information regarding the creation and manipulation of JSON values.接下来的几节提供了关于JSON值的创建和操作的基本信息。
A JSON array contains a list of values separated by commas and enclosed within JSON数组包含由逗号分隔并包含在[
and ]
characters:[
和]
字符内的值列表:
["abc", 10, null, true, false]
A JSON object contains a set of key-value pairs separated by commas and enclosed within JSON对象包含一组由逗号分隔并包含在{
and }
characters:{
和}
字符内的键值对:
{"k1": "value", "k2": 10}
As the examples illustrate, JSON arrays and objects can contain scalar values that are strings or numbers, the JSON null literal, or the JSON boolean true or false literals. 如示例所示,JSON数组和对象可以包含字符串或数字的标量值、JSON null
的文本或JSON 布尔值true
或false
的文本。Keys in JSON objects must be strings. JSON对象中的键必须是字符串。Temporal (date, time, or datetime) scalar values are also permitted:还允许使用时间(DATE
、TIME
或DATETIME
时间)标量值:
["12:18:29.000000", "2015-07-29", "2015-07-29 12:18:29.000000"]
Nesting is permitted within JSON array elements and JSON object key values:JSON数组元素和JSON对象键值中允许嵌套:
[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]] {"k1": "value", "k2": [10, 20]}
You can also obtain JSON values from a number of functions supplied by MySQL for this purpose (see Section 12.18.2, “Functions That Create JSON Values”) as well as by casting values of other types to the 您还可以从MySQL为此提供的许多函数中获取JSON值(请参阅第12.18.2节,“创建JSON值的函数”),也可以使用JSON
type using CAST(
(see Converting between JSON and non-JSON values). value
AS JSON)CAST(
将其他类型的值强制转换为value
AS JSON)JSON
类型(请参阅JSON值和非JSON值之间的转换)。The next several paragraphs describe how MySQL handles JSON values provided as input.接下来的几段将描述MySQL如何处理作为输入提供的JSON值。
In MySQL, JSON values are written as strings. 在MySQL中,JSON值被写成字符串。MySQL parses any string used in a context that requires a JSON value, and produces an error if it is not valid as JSON. MySQL解析在需要JSON值的上下文中使用的任何字符串,如果该字符串作为JSON无效,则生成错误。These contexts include inserting a value into a column that has the 这些上下文包括将值插入到具有JSON数据类型的列中,并将参数传递给需要JSON值的函数(在MySQL JSON函数的文档中通常显示为JSON
data type and passing an argument to a function that expects a JSON value (usually shown as json_doc
or json_val
in the documentation for MySQL JSON functions), as the following examples demonstrate:json_doc
或json_val
),如下示例所示:
Attempting to insert a value into a 如果值是有效的JSON
column succeeds if the value is a valid JSON value, but fails if it is not:JSON
值,则尝试将值插入JSON列会成功,如果不是,则会失败:
mysql>CREATE TABLE t1 (jdoc JSON);
Query OK, 0 rows affected (0.20 sec) mysql>INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
Query OK, 1 row affected (0.01 sec) mysql>INSERT INTO t1 VALUES('[1, 2,');
ERROR 3140 (22032) at line 2: Invalid JSON text: "Invalid value." at position 6 in value (or column) '[1, 2,'.
Positions for “at position 在这种错误消息中,“位置N”的位置是基于0的,但是应该被认为是一个值中问题实际发生位置的粗略指示。N
” in such error messages are 0-based, but should be considered rough indications of where the problem in a value actually occurs.
The JSON_TYPE()
function expects a JSON argument and attempts to parse it into a JSON value. JSON_TYPE()
函数需要一个JSON参数并尝试将其解析为JSON值。It returns the value's JSON type if it is valid and produces an error otherwise:如果值有效,则返回值的JSON类型,否则会产生错误:
mysql>SELECT JSON_TYPE('["a", "b", 1]');
+----------------------------+ | JSON_TYPE('["a", "b", 1]') | +----------------------------+ | ARRAY | +----------------------------+ mysql>SELECT JSON_TYPE('"hello"');
+----------------------+ | JSON_TYPE('"hello"') | +----------------------+ | STRING | +----------------------+ mysql>SELECT JSON_TYPE('hello');
ERROR 3146 (22032): Invalid data type for JSON data in argument 1 to function json_type; a JSON string or JSON type is required.
MySQL handles strings used in JSON context using the MySQL使用utf8mb4
character set and utf8mb4_bin
collation. utf8mb4
字符集和utf8mb4_bin
排序规则处理JSON上下文中使用的字符串。Strings in other character sets are converted to 其他字符集中的字符串根据需要转换为utf8mb4
as necessary. utf8mb4
。(For strings in the (对于ascii
or utf8
character sets, no conversion is needed because ascii
and utf8
are subsets of utf8mb4
.)ascii
或utf8
字符集中的字符串,不需要转换,因为ascii
和utf8
是utf8mb4
的子集。)
As an alternative to writing JSON values using literal strings, functions exist for composing JSON values from component elements. 作为使用文本字符串编写JSON值的替代方法,存在用于从组件元素合成JSON值的函数。JSON_ARRAY()
takes a (possibly empty) list of values and returns a JSON array containing those values:JSON_ARRAY()
获取一个(可能为空)值列表,并返回一个包含这些值的JSON数组:
mysql> SELECT JSON_ARRAY('a', 1, NOW());
+----------------------------------------+
| JSON_ARRAY('a', 1, NOW()) |
+----------------------------------------+
| ["a", 1, "2015-07-27 09:43:47.000000"] |
+----------------------------------------+
JSON_OBJECT()
takes a (possibly empty) list of key-value pairs and returns a JSON object containing those pairs:JSON_OBJECT()
获取一个键值对列表(可能为空),并返回一个包含这些键值对的JSON对象:
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc');
+---------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc') |
+---------------------------------------+
| {"key1": 1, "key2": "abc"} |
+---------------------------------------+
JSON_MERGE_PRESERVE()
takes two or more JSON documents and returns the combined result:JSON_MERGE_PRESERVE()
获取两个或多个JSON文档并返回组合结果:
mysql> SELECT JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}');
+-----------------------------------------------------+
| JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}') |
+-----------------------------------------------------+
| ["a", 1, {"key": "value"}] |
+-----------------------------------------------------+
1 row in set (0.00 sec)
For information about the merging rules, see Normalization, Merging, and Autowrapping of JSON Values.有关合并规则的信息,请参阅JSON值的规范化、合并和自动折行。
(MySQL 8.0.3 and later also support (MySQL 8.0.3及更高版本也支持JSON_MERGE_PATCH()
, which has somewhat different behavior. JSON_MERGE_PATCH()
,它的行为有些不同。See JSON_MERGE_PATCH() compared with JSON_MERGE_PRESERVE(), for information about the differences between these two functions.)有关这两个函数之间差异的信息,请参阅JSON_MERGE_PATCH()
与JSON_MERGE_PRESERVE()
的比较。)
JSON values can be assigned to user-defined variables:JSON值可以分配给用户定义的变量:
mysql>SET @j = JSON_OBJECT('key', 'value');
mysql>SELECT @j;
+------------------+ | @j | +------------------+ | {"key": "value"} | +------------------+
However, user-defined variables cannot be of 但是,用户定义的变量不能是JSON
data type, so although @j
in the preceding example looks like a JSON value and has the same character set and collation as a JSON value, it does not have the JSON
data type. JSON
数据类型,因此尽管前面示例中的@j
看起来像JSON值,并且具有与JSON值相同的字符集和排序规则,但它没有JSON数据类型。Instead, the result from 相反,JSON_OBJECT()
is converted to a string when assigned to the variable.JSON_OBJECT()
的结果在赋值给变量时会转换为字符串。
Strings produced by converting JSON values have a character set of 通过转换JSON值生成的字符串的字符集为utf8mb4
and a collation of utf8mb4_bin
:utf8mb4
,排序规则为utf8mb4_bin
:
mysql> SELECT CHARSET(@j), COLLATION(@j);
+-------------+---------------+
| CHARSET(@j) | COLLATION(@j) |
+-------------+---------------+
| utf8mb4 | utf8mb4_bin |
+-------------+---------------+
Because 因为utf8mb4_bin
is a binary collation, comparison of JSON values is case-sensitive.utf8mb4_bin
是二进制排序规则,所以比较JSON值是区分大小写的。
mysql> SELECT JSON_ARRAY('x') = JSON_ARRAY('X');
+-----------------------------------+
| JSON_ARRAY('x') = JSON_ARRAY('X') |
+-----------------------------------+
| 0 |
+-----------------------------------+
Case sensitivity also applies to the JSON 区分大小写也适用于JSON null
, true
, and false
literals, which always must be written in lowercase:null
、true
和false
文本,这些文本必须始终以小写形式编写:
mysql>SELECT JSON_VALID('null'), JSON_VALID('Null'), JSON_VALID('NULL');
+--------------------+--------------------+--------------------+ | JSON_VALID('null') | JSON_VALID('Null') | JSON_VALID('NULL') | +--------------------+--------------------+--------------------+ | 1 | 0 | 0 | +--------------------+--------------------+--------------------+ mysql>SELECT CAST('null' AS JSON);
+----------------------+ | CAST('null' AS JSON) | +----------------------+ | null | +----------------------+ 1 row in set (0.00 sec) mysql>SELECT CAST('NULL' AS JSON);
ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json: "Invalid value." at position 0 in 'NULL'.
Case sensitivity of the JSON literals differs from that of the SQL JSON文本的大小写敏感度与SQL NULL
, TRUE
, and FALSE
literals, which can be written in any lettercase:NULL
、TRUE
和FALSE
文本的大小写敏感度不同,SQL NULL
、TRUE
和FALSE
文本可以用任何字母大小写:
mysql> SELECT ISNULL(null), ISNULL(Null), ISNULL(NULL);
+--------------+--------------+--------------+
| ISNULL(null) | ISNULL(Null) | ISNULL(NULL) |
+--------------+--------------+--------------+
| 1 | 1 | 1 |
+--------------+--------------+--------------+
Sometimes it may be necessary or desirable to insert quote characters (有时,在JSON文档中插入引号字符("
or '
) into a JSON document. "
或'
)可能是必要的或可取的。Assume for this example that you want to insert some JSON objects containing strings representing sentences that state some facts about MySQL, each paired with an appropriate keyword, into a table created using the SQL statement shown here:在本例中,假设您希望将一些JSON对象插入到使用以下SQL语句创建的表中,这些JSON对象包含表示有关MySQL的一些事实的字符串,每个字符串都与相应的关键字配对:
mysql> CREATE TABLE facts (sentence JSON);
Among these keyword-sentence pairs is this one:在这些关键字句子对中,有这样一个:
mascot: The MySQL mascot is a dolphin named "Sakila".
One way to insert this as a JSON object into the 将其作为JSON对象插入facts
table is to use the MySQL JSON_OBJECT()
function. facts
表的一种方法是使用MySQL JSON_object()
函数。In this case, you must escape each quote character using a backslash, as shown here:在这种情况下,必须使用反斜杠转义每个引号字符,如下所示:
mysql>INSERT INTO facts VALUES
>(JSON_OBJECT("mascot", "Our mascot is a dolphin named \"Sakila\"."));
This does not work in the same way if you insert the value as a JSON object literal, in which case, you must use the double backslash escape sequence, like this:如果将值作为JSON对象文本插入,则工作方式不同,在这种情况下,必须使用双反斜杠转义序列,如下所示:
mysql>INSERT INTO facts VALUES
>('{"mascot": "Our mascot is a dolphin named \\"Sakila\\"."}');
Using the double backslash keeps MySQL from performing escape sequence processing, and instead causes it to pass the string literal to the storage engine for processing. 使用双反斜杠可以防止MySQL执行转义序列处理,而是使其将字符串文本传递给存储引擎进行处理。After inserting the JSON object in either of the ways just shown, you can see that the backslashes are present in the JSON column value by doing a simple 以上述任一方式插入JSON对象后,您可以通过执行简单的SELECT
, like this:SELECT
来看到JSON列值中存在反斜杠,如下所示:
mysql> SELECT sentence FROM facts;
+---------------------------------------------------------+
| sentence |
+---------------------------------------------------------+
| {"mascot": "Our mascot is a dolphin named \"Sakila\"."} |
+---------------------------------------------------------+
To look up this particular sentence employing 要查找使用mascot
as the key, you can use the column-path operator ->
, as shown here:mascot
作为键的特定句子,可以使用列路径运算符->
,如图所示:
mysql> SELECT col->"$.mascot" FROM qtest; +---------------------------------------------+ | col->"$.mascot" | +---------------------------------------------+ | "Our mascot is a dolphin named \"Sakila\"." | +---------------------------------------------+ 1 row in set (0.00 sec)
This leaves the backslashes intact, along with the surrounding quote marks. 这使得反斜杠和周围的引号保持不变。To display the desired value using 要使用mascot
as the key, but without including the surrounding quote marks or any escapes, use the inline path operator ->>
, like this:mascot
作为键显示所需的值,但不包括周围的引号或任何转义符,请使用内联路径运算符->>
,如下:
mysql> SELECT sentence->>"$.mascot" FROM facts;
+-----------------------------------------+
| sentence->>"$.mascot" |
+-----------------------------------------+
| Our mascot is a dolphin named "Sakila". |
+-----------------------------------------+
The previous example does not work as shown if the 如果启用了NO_BACKSLASH_ESCAPES
server SQL mode is enabled. NO_BACKSLASH_ESCAPES
server SQL模式,则上一个示例不会像所示那样工作。If this mode is set, a single backslash instead of double backslashes can be used to insert the JSON object literal, and the backslashes are preserved. 如果设置了此模式,则可以使用单反斜杠而不是双反斜杠插入JSON对象文本,并保留反斜杠。If you use the 如果在执行insert时使用JSON_OBJECT()
function when performing the insert and this mode is set, you must alternate single and double quotes, like this:JSON_OBJECT()
函数并设置了此模式,则必须交替使用单引号和双引号,如下所示:
mysql>INSERT INTO facts VALUES
>(JSON_OBJECT('mascot', 'Our mascot is a dolphin named "Sakila".'));
See the description of the 有关此模式对JSON值中转义字符的影响的详细信息,请参阅JSON_UNQUOTE()
function for more information about the effects of this mode on escaped characters in JSON values.JSON_UNQUOTE()
函数的说明。
When a string is parsed and found to be a valid JSON document, it is also normalized. 当字符串被解析并发现是有效的JSON文档时,它也会被规范化。This means that members with keys that duplicate a key found later in the document, reading from left to right, are discarded. 这意味着,如果成员的键与文档中稍后找到的键重复,则从左到右读取,将被丢弃。The object value produced by the following 以下JSON_OBJECT()
call includes only the second key1
element because that key name occurs earlier in the value, as shown here:JSON_object()
调用生成的对象值仅包含第二个key1
元素,因为该键名出现在值的前面,如下所示:
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": "def", "key2": "abc"} |
+------------------------------------------------------+
Normalization is also performed when values are inserted into JSON columns, as shown here:在JSON列中插入值时也会执行规范化,如下所示:
mysql>CREATE TABLE t1 (c1 JSON);
mysql>INSERT INTO t1 VALUES
>('{"x": 17, "x": "red"}'),
>('{"x": 17, "x": "red", "x": [3, 5, 7]}');
mysql>SELECT c1 FROM t1;
+------------------+ | c1 | +------------------+ | {"x": "red"} | | {"x": [3, 5, 7]} | +------------------+
This “last duplicate key wins” behavior is suggested by RFC 7159 and is implemented by most JavaScript parsers. 这种“最后一个复制密钥获胜”的行为是由RFC 7159建议的,并且是由大多数JavaScript解析器实现的。(Bug #86866, Bug #26369555)
In versions of MySQL prior to 8.0.3, members with keys that duplicated a key found earlier in the document were discarded. 在8.0.3之前的MySQL版本中,具有与文档中先前找到的键重复的键的成员被丢弃。The object value produced by the following 以下JSON_OBJECT()
call does not include the second key1
element because that key name occurs earlier in the value:JSON_object()
调用生成的对象值不包含第二个key1
元素,因为该键名出现在值的前面:
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": 1, "key2": "abc"} |
+------------------------------------------------------+
Prior to MySQL 8.0.3, this “first duplicate key wins” normalization was also performed when inserting values into JSON columns.在MySQL8.0.3之前,在JSON列中插入值时,也会执行这种“第一个重复的key-wins”规范化。
mysql>CREATE TABLE t1 (c1 JSON);
mysql>INSERT INTO t1 VALUES
>('{"x": 17, "x": "red"}'),
>('{"x": 17, "x": "red", "x": [3, 5, 7]}');
mysql>SELECT c1 FROM t1;
+-----------+ | c1 | +-----------+ | {"x": 17} | | {"x": 17} | +-----------+
MySQL also discards extra whitespace between keys, values, or elements in the original JSON document, and leaves (or inserts, when necessary) a single space following each comma (MySQL还丢弃了原始JSON文档中键、值或元素之间的额外空白,并在显示时在每个逗号(,
) or colon (:
) when displaying it. ,
)或冒号(:
)后留下(必要时插入)一个空格。This is done to enhance readibility.这样做是为了提高可读性。
MySQL functions that produce JSON values (see Section 12.18.2, “Functions That Create JSON Values”) always return normalized values.生成JSON值的MySQL函数(参见第12.18.2节,“创建JSON值的函数”)总是返回标准化值。
To make lookups more efficient, MySQL also sorts the keys of a JSON object. 为了提高查找效率,MySQL还对JSON对象的键进行排序。You should be aware that the result of this ordering is subject to change and not guaranteed to be consistent across releases.您应该知道,此订购的结果可能会发生更改,并且不能保证在各个版本中保持一致。
Two merging algorithms are supported in MySQL 8.0.3 (and later), implemented by the functions MySQL 8.0.3(及更高版本)支持两种合并算法,由函数JSON_MERGE_PRESERVE()
and JSON_MERGE_PATCH()
. JSON_MERGE_PRESERVE()
和JSON_MERGE_PATCH()
实现。These differ in how they handle duplicate keys: 它们处理重复键的方式有所不同:JSON_MERGE_PRESERVE()
retains values for duplicate keys, while JSON_MERGE_PATCH()
discards all but the last value. JSON_MERGE_PRESERVE()
保留重复键的值,而JSON_MERGE_PATCH()
丢弃除最后一个值以外的所有值。The next few paragraphs explain how each of these two functions handles the merging of different combinations of JSON documents (that is, of objects and arrays).接下来的几段将解释这两个函数如何处理JSON文档(即对象和数组)不同组合的合并。
JSON_MERGE_PRESERVE()
is the same as the JSON_MERGE()
function found in previous versions of MySQL (renamed in MySQL 8.0.3). JSON_MERGE_PRESERVE()
与以前版本的MySQL(在MySQL 8.0.3中重命名)中的JSON_MERGE()
函数相同。在MySQL 8.0中,JSON_MERGE()
is still supported as an alias for JSON_MERGE_PRESERVE()
in MySQL 8.0, but is deprecated and subject to removal in a future release.JSON_MERGE()
仍然被支持作为JSON_MERGE_PRESERVE()
的别名,但已被弃用,并可能在将来的版本中被删除。
Merging arrays.合并数组。 In contexts that combine multiple arrays, the arrays are merged into a single array. 在组合多个数组的上下文中,这些数组合并到单个数组中。JSON_MERGE_PRESERVE()
does this by concatenating arrays named later to the end of the first array. JSON_MERGE_PRESERVE()
通过将稍后命名的数组连接到第一个数组的末尾来实现这一点。JSON_MERGE_PATCH()
considers each argument as an array consisting of a single element (thus having 0 as its index) and then applies “last duplicate key wins” logic to select only the last argument. JSON_MERGE_PATCH()
将每个参数视为一个由单个元素组成的数组(因此索引为0),然后应用“最后重复键赢”逻辑仅选择最后一个参数。You can compare the results shown by this query:您可以比较此查询显示的结果:
mysql>SELECT
->JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Preserve,
->JSON_MERGE_PATCH('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Patch\G
*************************** 1. row *************************** Preserve: [1, 2, "a", "b", "c", true, false] Patch: [true, false]
Multiple objects when merged produce a single object. 合并多个对象时会生成单个对象。JSON_MERGE_PRESERVE()
handles multiple objects having the same key by combining all unique values for that key in an array; this array is then used as the value for that key in the result. JSON_MERGE_PRESERVE()
通过组合数组中该键的所有唯一值来处理具有相同键的多个对象;然后将此数组用作结果中该键的值。JSON_MERGE_PATCH()
discards values for which duplicate keys are found, working from left to right, so that the result contains only the last value for that key. JSON_MERGE_PATCH()
从左到右丢弃找到重复键的值,以便结果只包含该键的最后一个值。The following query illustrates the difference in the results for the duplicate key 以下查询说明了重复键a
:a
的结果差异:
mysql>SELECT
->JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,
->JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch\G
*************************** 1. row *************************** Preserve: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3} Patch: {"a": 4, "b": 2, "c": 5, "d": 3}
Nonarray values used in a context that requires an array value are autowrapped: The value is surrounded by 在需要数组值的上下文中使用的非数组值是自动包装的:该值被[
and ]
characters to convert it to an array. [
和]
字符包围,以将其转换为数组。In the following statement, each argument is autowrapped as an array (在下面的语句中,每个参数都自动包装为一个数组([1]
, [2]
). [1]
,[2]
)。These are then merged to produce a single result array; as in the previous two cases, 然后合并这些结果以生成单个结果数组;与前两种情况一样,JSON_MERGE_PRESERVE()
combines values having the same key while JSON_MERGE_PATCH()
discards values for all duplicate keys except the last, as shown here:JSON_MERGE_PRESERVE()
组合具有相同键的值,而JSON_MERGE_PATCH()
丢弃除最后一个键以外的所有重复键的值,如下所示:
mysql>SELECT
->JSON_MERGE_PRESERVE('1', '2') AS Preserve,
->JSON_MERGE_PATCH('1', '2') AS Patch\G
*************************** 1. row *************************** Preserve: [1, 2] Patch: 2
Array and object values are merged by autowrapping the object as an array and merging the arrays by combining values or by “last duplicate key wins” according to the choice of merging function (数组和对象值是通过将对象自动包装为数组并通过组合值或根据合并函数的选择(分别是JSON_MERGE_PRESERVE()
or JSON_MERGE_PATCH()
, respectively), as can be seen in this example:JSON_MERGE_PRESERVE()
或JSON_MERGE_PATCH()
)通过“最后一个重复键赢”来合并数组来合并的,如本例所示:
mysql>SELECT
->JSON_MERGE_PRESERVE('[10, 20]', '{"a": "x", "b": "y"}') AS Preserve,
->JSON_MERGE_PATCH('[10, 20]', '{"a": "x", "b": "y"}') AS Patch\G
*************************** 1. row *************************** Preserve: [10, 20, {"a": "x", "b": "y"}] Patch: {"a": "x", "b": "y"}
A JSON path expression selects a value within a JSON document.JSON路径表达式在JSON文档中选择一个值。
Path expressions are useful with functions that extract parts of or modify a JSON document, to specify where within that document to operate. 路径表达式对于提取或修改JSON文档部分的函数非常有用,可以指定在该文档中操作的位置。For example, the following query extracts from a JSON document the value of the member with the 例如,以下查询从JSON文档中提取具有name
key:name
键的成员的值:
mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan" |
+---------------------------------------------------------+
Path syntax uses a leading 路径语法使用一个前导$
character to represent the JSON document under consideration, optionally followed by selectors that indicate successively more specific parts of the document:$
字符来表示正在考虑的JSON文档,可选地后跟选择器,依次指示文档的更具体部分:
A period followed by a key name names the member in an object with the given key. 后跟键名的句点用给定键命名对象中的成员。The key name must be specified within double quotation marks if the name without quotes is not legal within path expressions (for example, if it contains a space).如果不带引号的名称在路径表达式中不合法(例如,如果包含空格),则必须在双引号内指定键名称。
[
appended to a N
]path
that selects an array names the value at position N
within the array. [
附加到选择数组的路径后,将数组中位置N
]N
处的值命名。Array positions are integers beginning with zero. 数组位置是从零开始的整数。If 如果path
does not select an array value, path
[0] evaluates to the same value as path
:path
未选择数组值,则path
[0]的计算结果与path
相同:
mysql> SELECT JSON_SET('"x"', '$[0]', 'a');
+------------------------------+
| JSON_SET('"x"', '$[0]', 'a') |
+------------------------------+
| "a" |
+------------------------------+
1 row in set (0.00 sec)
[
M
to N
] specifies a subset or range of array values starting with the value at position 指定数组值的子集或范围,从位置M
, and ending with the value at position N
.M
处的值开始,到位置N
处的值结束。
last
is supported as a synonym for the index of the rightmost array element. 支持作为最右边数组元素索引的同义词。Relative addressing of array elements is also supported. 还支持数组元素的相对寻址。If 如果path
does not select an array value, path
[last] evaluates to the same value as path
, as shown later in this section (see Rightmost array element).path
没有选择数组值,则path
[last]的计算结果与path
的值相同,如本节后面所示(请参见最右边的数组元素)。
Paths can contain 路径可以包含*
or **
wildcards:*
或**
通配符:
.[*]
evaluates to the values of all members in a JSON object.计算为JSON对象中所有成员的值。
[*]
evaluates to the values of all elements in a JSON array.计算为JSON数组中所有元素的值。
prefix
**suffix
evaluates to all paths that begin with the named prefix and end with the named suffix.计算以命名前缀开始并以命名后缀结束的所有路径。
A path that does not exist in the document (evaluates to nonexistent data) evaluates to 文档中不存在的路径(计算结果为不存在的数据)计算结果为NULL
.NULL
。
Let 让$
refer to this JSON array with three elements:$
引用这个包含三个元素的JSON数组:
[3, {"a": [5, 6], "b": 10}, [99, 100]]
Then:则:
$[0]
evaluates to 计算结果为3
.3
。
$[1]
evaluates to 计算结果为{"a": [5, 6], "b": 10}
.{"a": [5, 6], "b": 10}
。
$[2]
evaluates to 计算结果为[99, 100]
.[99, 100]
。
$[3]
evaluates to 计算结果为NULL
(it refers to the fourth array element, which does not exist).NULL
(它引用不存在的第四个数组元素)。
Because 因为$[1]
and $[2]
evaluate to nonscalar values, they can be used as the basis for more-specific path expressions that select nested values. $[1]
和$[2]
的计算结果是非标量值,所以它们可以用作选择嵌套值的更具体路径表达式的基础。Examples:例如:
$[1].a
evaluates to 等于[5, 6]
.[5, 6]
。
$[1].a[1]
evaluates to 等于6
.6
。
$[1].b
evaluates to 等于10
.10
。
$[2][0]
evaluates to 等于99
.99
。
As mentioned previously, path components that name keys must be quoted if the unquoted key name is not legal in path expressions. 如前所述,如果未加引号的键名在路径表达式中不合法,则必须引用命名键的路径组件。Let 让$
refer to this value:$
引用此值:
{"a fish": "shark", "a bird": "sparrow"}
The keys both contain a space and must be quoted:这两个键都包含空格,必须加引号:
$."a fish"
evaluates to shark
.$."a fish"
等于shark
。
$."a bird"
evaluates to sparrow
.$."a bird"
等于sparrow
。
Paths that use wildcards evaluate to an array that can contain multiple values:使用通配符的路径计算为可以包含多个值的数组:
mysql>SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
+---------------------------------------------------------+ | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') | +---------------------------------------------------------+ | [1, 2, [3, 4, 5]] | +---------------------------------------------------------+ mysql>SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
+------------------------------------------------------------+ | JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') | +------------------------------------------------------------+ | [3, 4, 5] | +------------------------------------------------------------+
In the following example, the path 在以下示例中,路径$**.b
evaluates to multiple paths ($.a.b
and $.c.b
) and produces an array of the matching path values:$**.b
计算为多个路径($.a.b
和$.c.b
),并生成匹配路径值的数组:
mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
+---------------------------------------------------------+
| [1, 2] |
+---------------------------------------------------------+
Ranges from JSON arrays.来自JSON数组的范围。 You can use ranges with the 可以利用to
keyword to specify subsets of JSON arrays. to
关键字使用范围,它用来指定JSON数组的子集。For example, 例如,$[1 to 3]
includes the second, third, and fourth elements of an array, as shown here:$[1 to 3]
包括数组的第二、第三和第四个元素,如下所示:
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]');
+----------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]') |
+----------------------------------------------+
| [2, 3, 4] |
+----------------------------------------------+
1 row in set (0.00 sec)
The syntax is 语法是
, where M
to N
M
and N
are, respectively, the first and last indexes of a range of elements from a JSON array.
,其中M
to N
M
和N
分别是JSON数组中一系列元素的第一个和最后一个索引。N
must be greater than M
; M
must be greater than or equal to 0. N
必须大于M
;M
必须大于或等于0。Array elements are indexed beginning with 0.数组元素的索引从0开始。
You can use ranges in contexts where wildcards are supported.可以在支持通配符的上下文中使用范围。
Rightmost array element.最右边的数组元素。 The last
keyword is supported as a synonym for the index of the last element in an array. last
关键字支持作为数组中最后一个元素的索引的同义词。Expressions of the form 形式为last -
can be used for relative addressing, and within range definitions, like this:N
last-N
的表达式可用于相对寻址和范围内定义,如下所示:
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]');
+--------------------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]') |
+--------------------------------------------------------+
| [2, 3, 4] |
+--------------------------------------------------------+
1 row in set (0.01 sec)
If the path is evaluated against a value that is not an array, the result of the evaluation is the same as if the value had been wrapped in a single-element array:如果针对非数组的值对路径求值,则求值结果与将该值包装在单个元素数组中的结果相同:
mysql> SELECT JSON_REPLACE('"Sakila"', '$[last]', 10); +-----------------------------------------+ | JSON_REPLACE('"Sakila"', '$[last]', 10) | +-----------------------------------------+ | 10 | +-----------------------------------------+ 1 row in set (0.00 sec)
You can use 您可以使用带有JSON列标识符和JSON路径表达式的
with a JSON column identifier and JSON path expression as a synonym for column
->path
JSON_EXTRACT(
. column
, path
)
,作为column
->path
JSON_EXTRACT(
的同义词。column
, path
)See Section 12.18.3, “Functions That Search JSON Values”, for more information. 有关更多信息,请参阅第12.18.3节,“搜索JSON值的函数”。See also Indexing a Generated Column to Provide a JSON Column Index.另请参阅索引生成的列以提供JSON列索引。
Some functions take an existing JSON document, modify it in some way, and return the resulting modified document. 有些函数获取现有的JSON文档,以某种方式对其进行修改,并返回修改后的文档。Path expressions indicate where in the document to make changes. 路径表达式指示要在文档中的何处进行更改。For example, the 例如,JSON_SET()
, JSON_INSERT()
, and JSON_REPLACE()
functions each take a JSON document, plus one or more path-value pairs that describe where to modify the document and the values to use. JSON_SET()
、JSON_INSERT()
和JSON_REPLACE()
函数分别获取一个JSON文档,以及一个或多个描述在何处修改文档和要使用的值的路径值对。The functions differ in how they handle existing and nonexisting values within the document.函数处理文档中现有值和不存在值的方式不同。
Consider this document:考虑本文件:
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
JSON_SET()
replaces values for paths that exist and adds values for paths that do not exist:.JSON_SET()
替换现有路径的值,并为不存在的路径添加值:
mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20, 2]] |
+--------------------------------------------+
In this case, the path 在本例中,路径$[1].b[0]
selects an existing value (true
), which is replaced with the value following the path argument (1
). $[1].b[0]
选择一个现有值(true
),该值将替换为路径参数(1
)后面的值。The path 路径$[2][2]
does not exist, so the corresponding value (2
) is added to the value selected by $[2]
.$[2][2]
不存在,因此相应的值(2
)被添加到由$[2]
选择的值中。
JSON_INSERT()
adds new values but does not replace existing values:JSON_INSERT()
添加新值但不替换现有值:
mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {"b": [true, false]}, [10, 20, 2]] |
+-----------------------------------------------+
JSON_REPLACE()
replaces existing values and ignores new values:JSON_REPLACE()
替换现有值并忽略新值:
mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20]] |
+------------------------------------------------+
The path-value pairs are evaluated left to right. 路径值对从左到右求值。The document produced by evaluating one pair becomes the new value against which the next pair is evaluated.通过对一对进行求值而生成的文档将成为下一对的求值所依据的新值。
JSON_REMOVE()
takes a JSON document and one or more paths that specify values to be removed from the document. JSON_REMOVE()
接受一个JSON文档和一个或多个指定要从文档中删除的值的路径。The return value is the original document minus the values selected by paths that exist within the document:返回值是原始文档减去文档中存在的路径选择的值:
mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {"b": [true]}] |
+---------------------------------------------------+
The paths have these effects:路径具有以下效果:
$[2]
matches [10, 20]
and removes it.$[2]
匹配[10, 20]
并将其删除。
The first instance of $[1].b[1]
matches false
in the b
element and removes it.$[1].b[1]
的第一个实例匹配b
元素中的false
并将其删除。
The second instance of $[1].b[1]
matches nothing: That element has already been removed, the path no longer exists, and has no effect.$[1].b[1]
的第二个实例与任何内容都不匹配:该元素已被删除,路径不再存在,并且无效。
Many of the JSON functions supported by MySQL and described elsewhere in this Manual (see Section 12.18, “JSON Functions”) require a path expression in order to identify a specific element in a JSON document. MySQL支持并在本手册其他地方介绍的许多JSON函数(参见第12.18节,“JSON函数”)都需要一个路径表达式来标识JSON文档中的特定元素。A path consists of the path's scope followed by one or more path legs. 路径由路径的作用域后跟一个或多个路径分支组成。For paths used in MySQL JSON functions, the scope is always the document being searched or otherwise operated on, represented by a leading 对于MySQL JSON函数中使用的路径,作用域始终是正在搜索或以其他方式操作的文档,由前导$
character. $
字符表示。Path legs are separated by period characters (路径分支由句点字符(.
). .
)分隔。Cells in arrays are represented by 数组中的单元格由[
, where N
]N
is a non-negative integer. [
表示,其中N
]N
是非负整数。Names of keys must be double-quoted strings or valid ECMAScript identifiers (see Identifier Names and Identifiers, in the ECMAScript Language Specification). 键的名称必须是双引号字符串或有效的ECMAScript标识符(请参阅ECMAScript语言规范文档中的标识符名称和标识符)。Path expressions, like JSON text, should be encoded using the 路径表达式(如JSON文本)应使用ascii
, utf8
, or utf8mb4
character set. ascii
、utf8
或utf8mb4
字符集进行编码。Other character encodings are implicitly coerced to 其他字符编码隐式强制为utf8mb4
. utf8mb4
。The complete syntax is shown here:完整的语法如下所示:
pathExpression
:scope
[(pathLeg
)*]pathLeg
:member
|arrayLocation
|doubleAsterisk
member
:period
(keyName
|asterisk
)arrayLocation
:leftBracket
(nonNegativeInteger
|asterisk
)rightBracket
keyName
:ESIdentifier
|doubleQuotedString
doubleAsterisk
: '**'period
: '.'asterisk
: '*'leftBracket
: '['rightBracket
: ']'
As noted previously, in MySQL, the scope of the path is always the document being operated on, represented as 如前所述,在MySQL中,路径的作用域总是操作的文档,用$
. $
表示。You can use 您可以使用'$'
as a synonynm for the document in JSON path expressions.'$'
作为JSON路径表达式中文档的同义词。
Some implementations support column references for scopes of JSON paths; currently, MySQL does not support these.一些实现支持JSON路径范围的列引用;目前,MySQL不支持这些。
The wildcard 通配符*
and **
tokens are used as follows:*
和**
标记的用法如下:
.*
represents the values of all members in the object..*
表示对象中所有成员的值。
[*]
represents the values of all cells in the array.[*]
表示数组中所有单元格的值。
[
prefix
]**suffix
represents all paths beginning with 表示以prefix
and ending with suffix
. prefix
开头并以suffix
结尾的所有路径。prefix
is optional, while suffix
is required; in other words, a path may not end in **
.prefix
是可选的,suffix
是必需的;换句话说,路径不能以**
结束。
In addition, a path may not contain the sequence 此外,路径不能包含序列***
.***
。
For path syntax examples, see the descriptions of the various JSON functions that take paths as arguments, such as 有关路径语法示例,请参阅以路径为参数的各种JSON函数的说明,例如JSON_CONTAINS_PATH()
, JSON_SET()
, and JSON_REPLACE()
. JSON_CONTAINS_path()
、JSON_SET()
和JSON_REPLACE()
。For examples which include the use of the 有关使用*
and **
wildcards, see the description of the JSON_SEARCH()
function.*
和**
通配符的示例,请参阅JSON_SEARCH()
函数的说明。
MySQL 8.0.2 and later also supports range notation for subsets of JSON arrays using the MySQL 8.0.2及更高版本还支持使用to
keyword (such as $[2 to 10]
), as well as the last
keyword as a synonym for the rightmost element of an array. to
关键字(例如$[2 to 10]
)以及last
关键字作为数组最右边元素同义词的JSON数组子集的范围表示法。See Searching and Modifying JSON Values, for more information and examples.有关更多信息和示例,请参阅搜索和修改JSON值。
JSON values can be compared using the JSON值可以使用=
, <
, <=
, >
, >=
, <>
, !=
, and <=>
operators.=
,<
、<=
、>
、>=
、<>
、!=
和<=>
运算符。
The following comparison operators and functions are not yet supported with JSON values:JSON值尚不支持以下比较运算符和函数:
A workaround for the comparison operators and functions just listed is to cast JSON values to a native MySQL numeric or string data type so they have a consistent non-JSON scalar type.刚才列出的比较运算符和函数的一个解决方法是将JSON值强制转换为原生MySQL数值或字符串数据类型,以便它们具有一致的非JSON标量类型。
Comparison of JSON values takes place at two levels. JSON值的比较在两个级别上进行。The first level of comparison is based on the JSON types of the compared values. 第一级比较基于比较值的JSON类型。If the types differ, the comparison result is determined solely by which type has higher precedence. 如果类型不同,则比较结果仅取决于哪个类型具有更高的优先级。If the two values have the same JSON type, a second level of comparison occurs using type-specific rules.如果这两个值具有相同的JSON类型,则使用特定于类型的规则进行第二级比较。
The following list shows the precedences of JSON types, from highest precedence to the lowest. 下面的列表显示了JSON类型的优先级,从最高优先级到最低优先级。(The type names are those returned by the (类型名称是由JSON_TYPE()
function.) JSON_type()
函数返回的名称。)Types shown together on a line have the same precedence. 一行中同时显示的类型具有相同的优先级。Any value having a JSON type listed earlier in the list compares greater than any value having a JSON type listed later in the list.列表前面列出的JSON类型的任何值都比列表后面列出的JSON类型的任何值大。
BLOB BIT OPAQUE DATETIME TIME DATE BOOLEAN ARRAY OBJECT STRING INTEGER, DOUBLE NULL
For JSON values of the same precedence, the comparison rules are type specific:对于具有相同优先级的JSON值,比较规则是特定于类型的:
BLOB
The first 比较两个值的前N
bytes of the two values are compared, where N
is the number of bytes in the shorter value. N
个字节,其中N
是较短值中的字节数。If the first 如果两个值的前N
bytes of the two values are identical, the shorter value is ordered before the longer value.N
个字节相同,则较短的值在较长的值之前排序。
BIT
Same rules as for 与BLOB
.BLOB
的规则相同。
OPAQUE
Same rules as for 与BLOB
. BLOB
的规则相同。不透明值是未分类为其他类型之一的值。OPAQUE
values are values that are not classified as one of the other types.
DATETIME
A value that represents an earlier point in time is ordered before a value that represents a later point in time. 表示较早时间点的值在表示较后时间点的值之前排序。If two values originally come from the MySQL 如果两个值最初分别来自MySQL DATETIME
and TIMESTAMP
types, respectively, they are equal if they represent the same point in time.DATETIME
和TIMESTAMP
类型,那么如果它们表示相同的时间点,那么它们是相等的。
TIME
The smaller of two time values is ordered before the larger one.两个时间值中的较小值排在较大值之前。
DATE
The earlier date is ordered before the more recent date.较早的日期在较近的日期之前。
ARRAY
Two JSON arrays are equal if they have the same length and values in corresponding positions in the arrays are equal.如果两个JSON数组具有相同的长度,并且数组中相应位置的值相等,则它们是相等的。
If the arrays are not equal, their order is determined by the elements in the first position where there is a difference. 如果数组不相等,则其顺序由第一个位置的元素确定,其中存在差异。The array with the smaller value in that position is ordered first. 首先对该位置中值较小的数组进行排序。If all values of the shorter array are equal to the corresponding values in the longer array, the shorter array is ordered first.如果较短数组的所有值都等于较长数组中的相应值,则先对较短数组排序。
Example:例如:
[] < ["a"] < ["ab"] < ["ab", "cd", "ef"] < ["ab", "ef"]
BOOLEAN
The JSON false literal is less than the JSON true literal.JSONfalse
文本小于JSONtrue
文本。
OBJECT
Two JSON objects are equal if they have the same set of keys, and each key has the same value in both objects.如果两个JSON对象具有相同的键集,并且每个键在两个对象中具有相同的值,那么它们是相等的。
Example:例如:
{"a": 1, "b": 2} = {"b": 2, "a": 1}
The order of two objects that are not equal is unspecified but deterministic.两个不相等的对象的顺序是不确定的,但却是确定的。
STRING
Strings are ordered lexically on the first 字符串是按要比较的两个字符串的N
bytes of the utf8mb4
representation of the two strings being compared, where N
is the length of the shorter string. utf8mb4
表示的前N
个字节进行词汇排序的,其中N
是较短字符串的长度。If the first 如果两个字符串的前N
bytes of the two strings are identical, the shorter string is considered smaller than the longer string.N
个字节相同,则认为较短的字符串小于较长的字符串。
Example:例如:
"a" < "ab" < "b" < "bc"
This ordering is equivalent to the ordering of SQL strings with collation 这种排序相当于排序规则为utf8mb4_bin
. utf8mb4_bin
的SQL字符串的排序。Because 因为utf8mb4_bin
is a binary collation, comparison of JSON values is case-sensitive:utf8mb4_bin
是一个二进制排序规则,所以JSON值的比较区分大小写:
"A" < "a"
INTEGER
, DOUBLE
JSON values can contain exact-value numbers and approximate-value numbers. JSON值可以包含精确值和近似值。For a general discussion of these types of numbers, see Section 9.1.2, “Numeric Literals”.有关这些类型的数字的一般性讨论,请参阅第9.1.2节,“数字文字”。
The rules for comparing native MySQL numeric types are discussed in Section 12.3, “Type Conversion in Expression Evaluation”, but the rules for comparing numbers within JSON values differ somewhat:比较原生MySQL数值类型的规则在第12.3节,“表达式求值中的类型转换”中进行了讨论,但是比较JSON值中的数字的规则有些不同:
In a comparison between two columns that use the native MySQL 在分别使用原生MySQL INT
and DOUBLE
numeric types, respectively, it is known that all comparisons involve an integer and a double, so the integer is converted to double for all rows. INT
和DOUBLE
数字类型的两个列之间进行比较时,我们知道所有比较都涉及一个整型数和一个双精度浮点数,因此所有行的整数都转换为DOUBLE。That is, exact-value numbers are converted to approximate-value numbers.也就是说,精确值转换为近似值。
On the other hand, if the query compares two JSON columns containing numbers, it cannot be known in advance whether numbers are integer or double. 另一方面,如果查询比较两个包含数字的JSON列,则无法预先知道数字是整数还是双精度。To provide the most consistent behavior across all rows, MySQL converts approximate-value numbers to exact-value numbers. 为了在所有行中提供最一致的行为,MySQL将近似值转换为精确值。The resulting ordering is consistent and does not lose precision for the exact-value numbers. 结果排序是一致的,并且不会损失精确值数字的精度。For example, given the scalars 9223372036854775805, 9223372036854775806, 9223372036854775807 and 9.223372036854776e18, the order is such as this:例如,给定标量9223372036854775805、9223372036854775806、9223372036854775807和9.223372036854776e18,顺序如下:
9223372036854775805 < 9223372036854775806 < 9223372036854775807 < 9.223372036854776e18 = 9223372036854776000 < 9223372036854776001
Were JSON comparisons to use the non-JSON numeric comparison rules, inconsistent ordering could occur. 如果JSON比较使用非JSON数字比较规则,则可能会出现顺序不一致的情况。The usual MySQL comparison rules for numbers yield these orderings:通常的MySQL数字比较规则产生以下顺序:
Integer comparison:整数比较:
9223372036854775805 < 9223372036854775806 < 9223372036854775807
(not defined for 9.223372036854776e18)(未定义为9.223372036854776e18)
Double comparison:双重比较:
9223372036854775805 = 9223372036854775806 = 9223372036854775807 = 9.223372036854776e18
For comparison of any JSON value to SQL 对于任何JSON值与SQL NULL
, the result is UNKNOWN
.NULL
的比较,结果都是未知的。
For comparison of JSON and non-JSON values, the non-JSON value is converted to JSON according to the rules in the following table, then the values compared as described previously.为了比较JSON和非JSON值,根据下表中的规则将非JSON值转换为JSON,然后按照前面的描述比较值。
The following table provides a summary of the rules that MySQL follows when casting between JSON values and values of other types:下表总结了MySQL在JSON值和其他类型的值之间转换时遵循的规则:
Table 11.3 JSON Conversion RulesJSON转换规则
CAST(other type AS JSON) | CAST(JSON AS other type) | |
---|---|---|
JSON | ||
utf8 character type (utf8mb4 ,
utf8 , ascii ) | utf8mb4 string.utf8mb4 字符串。 |
|
utf8mb4 and treated as described for utf8 character type.utf8mb4 ,并按utf8字符类型所述进行处理。 | utf8mb4 string, then cast to the other character encoding. utf8mb4 字符串,然后转换为另一个字符编码。 |
|
NULL | NULL value of type JSON.NULL 值。 | |
ST_AsGeoJSON() .ST_AsGeoJSON() 转换为JSON文档。 | CAST( to ST_GeomFromGeoJSON() .CAST( 的结果传递给ST_GeomFromGeoJSON() 。 |
|
NULL and produces a warning.NULL 并生成警告。 |
JSON值的ORDER BY
and GROUP BY
for JSON values works according to these principles:ORDER BY
和GROUP BY
根据以下原则工作:
Ordering of scalar JSON values uses the same rules as in the preceding discussion.标量JSON值的排序使用与前面讨论中相同的规则。
For ascending sorts, SQL 对于升序排序,SQL NULL
orders before all JSON values, including the JSON null literal; for descending sorts, SQL NULL
orders after all JSON values, including the JSON null literal.NULL
在所有JSON值之前排序,包括JSON null
文本;对于降序排序,sql NULL
在所有JSON值之后排序,包括JSON null
文本。
Sort keys for JSON values are bound by the value of the JSON值的排序键由max_sort_length
system variable, so keys that differ only after the first max_sort_length
bytes compare as equal.max_Sort_length
系统变量的值绑定,因此只有在第一个max_Sort_length
字节之后不同的键才会比较为相等。
Sorting of nonscalar values is not currently supported and a warning occurs.当前不支持对非标量值进行排序,并出现警告。
For sorting, it can be beneficial to cast a JSON scalar to some other native MySQL type. 对于排序,将JSON标量转换为其他原生MySQL类型可能是有益的。For example, if a column named 例如,如果名为jdoc
contains JSON objects having a member consisting of an id
key and a nonnegative value, use this expression to sort by id
values:jdoc
的列包含具有由id
键和非负值组成的成员的JSON对象,请使用此表达式按id
值排序:
ORDER BY CAST(JSON_EXTRACT(jdoc, '$.id') AS UNSIGNED)
If there happens to be a generated column defined to use the same expression as in the 如果碰巧有一个生成的列被定义为使用与ORDER BY
, the MySQL optimizer recognizes that and considers using the index for the query execution plan. ORDER BY
中相同的表达式,MySQL优化器会识别出这一点,并考虑将索引用于查询执行计划。See Section 8.3.11, “Optimizer Use of Generated Column Indexes”.请参阅第8.3.11节,“优化器使用生成的列索引”。
For aggregation of JSON values, SQL 对于JSON值的聚合,SQLNULL
values are ignored as for other data types. NULL
值与其他数据类型一样被忽略。Non-非NULL
values are converted to a numeric type and aggregated, except for MIN()
, MAX()
, and GROUP_CONCAT()
. NULL
值将转换为数字类型并聚合,但MIN()
、MAX()
和GROUP_CONCAT()
除外。The conversion to number should produce a meaningful result for JSON values that are numeric scalars, although (depending on the values) truncation and loss of precision may occur. 对数字的转换应该为数字标量的JSON值产生有意义的结果,尽管(取决于值)可能会发生截断和精度损失。Conversion to number of other JSON values may not produce a meaningful result.转换为其他JSON值的数目可能不会产生有意义的结果。