当解析字符串并发现它是有效的 JSON 文档时,该字符串也会被标准化。这意味着,其键与文档后面找到的键(从左到右读取)的副本将被丢弃。由以下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"} |
+------------------------------------------------------+
当值插入 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]} |
+------------------+
这种"最后一个重复键获胜"的行为是由RFC 7159建议的,并且由大多数JavaScript解析器实现。(错误 86866,错误 26369555)
在 8.0.3 之前的 MySQL 版本中,其密钥与文档前面找到的密钥重复的成员将被丢弃。由以下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"} |
+------------------------------------------------------+
在MySQL 8.0.3之前,在将值插入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": 17} |
| {"x": 17} |
+-----------+
MySQL还会丢弃原始JSON文档中键,值或元素之间的额外空格,并在显示时在每个逗号()或冒号()后留下(或在必要时插入)一个空格。这样做是为了增强可读性。,
:
生成 JSON 值的 MySQL 函数(请参见第 12.18.2 节 "创建 JSON 值的函数")始终返回标准化值。
为了使查找更有效率,MySQL还对JSON对象的键进行排序。您应该知道,此订购的结果可能会发生变化,并且不保证在各个版本之间保持一致。