12.17.6 JSONUtil 功能

本节介绍了作用于 JSON 值的 Util 函数,或可以解析为 JSON 值的字符串。 JSON_PRETTY()以易于阅读的格式输出 JSON 值。 JSON_STORAGE_SIZE()显示给定 JSON 值使用的存储空间量。

JSON_PRETTY(json_val)

提供漂亮的 JSON 值打印,类似于用 PHP 以及其他语言和数据库系统实现的 JSON 值。提供的值必须是 JSON 值或 JSON 值的有效字符串 table 示形式。此值中存在多余的空格和换行符对输出没有影响。对于NULL值,函数返回NULL。如果该值不是 JSON 文档,或者无法将其解析为一个文档,则该函数将失败并显示错误。

此函数的输出格式遵循以下规则:

  • 每个数组元素或对象成员显示在单独的行上,与其父级相比缩进了一个附加级别。

    • 每个缩进级别都会添加两个前导空格。

    • 在分隔两个元素或成员的换行符之前,将逗号分隔开单个数组元素或对象成员。

    • 对象成员的键和值由冒号和空格(“ :”)分隔。

    • 空对象或数组将打印在一行上。左括号和右括号之间没有印刷空间。

    • 字符串标量和键名中的特殊字符采用JSON_QUOTE()函数所使用的相同规则进行转义。

mysql> SELECT JSON_PRETTY('123'); # scalar
+--------------------+
| JSON_PRETTY('123') |
+--------------------+
| 123                |
+--------------------+

mysql> SELECT JSON_PRETTY("[1,3,5]"); # array
+------------------------+
| JSON_PRETTY("[1,3,5]") |
+------------------------+
| [
  1,
  3,
  5
]      |
+------------------------+

mysql> SELECT JSON_PRETTY('{"a":"10","b":"15","x":"25"}'); # object
+---------------------------------------------+
| JSON_PRETTY('{"a":"10","b":"15","x":"25"}') |
+---------------------------------------------+
| {
  "a": "10",
  "b": "15",
  "x": "25"
}   |
+---------------------------------------------+

mysql> SELECT JSON_PRETTY('["a",1,{"key1":
     >    "value1"},"5",     "77" ,
     >       {"key2":["value3","valueX",
     > "valueY"]},"j", "2"   ]')\G  # nested arrays and objects
*************************** 1. row ***************************
JSON_PRETTY('["a",1,{"key1":
             "value1"},"5",     "77" ,
                {"key2":["value3","valuex",
          "valuey"]},"j", "2"   ]'): [
  "a",
  1,
  {
    "key1": "value1"
  },
  "5",
  "77",
  {
    "key2": [
      "value3",
      "valuex",
      "valuey"
    ]
  },
  "j",
  "2"
]

在 MySQL 5.7.22 中添加。

JSON_STORAGE_SIZE(json_val)

此函数返回用于存储 JSON 文档的二进制 table 示形式的字节数。当参数是JSON列时,这是用于存储 JSON 文档的空间。 * json_val *必须是有效的 JSON 文档或可以解析为一个字符串。如果是字符串,该函数将通过将字符串解析为 JSON 并将其转换为二进制来创建 JSON 二进制 table 示形式,以返回存储空间量。如果参数为NULL,则返回NULL

  • json_val *不是NULL且不是(或无法成功解析为)JSON 文档时,将导致错误。

为了说明此函数在使用JSON列作为参数时的行为,我们创建了一个名为jtable的 table,其中包含JSONjcol,在 table 中插入 JSON 值,然后使用JSON_STORAGE_SIZE()获得此列使用的存储空间,如下所示:

mysql> CREATE TABLE jtable (jcol JSON);
Query OK, 0 rows affected (0.42 sec)

mysql> INSERT INTO jtable VALUES
    ->     ('{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}');
Query OK, 1 row affected (0.04 sec)

mysql> SELECT
    ->     jcol,
    ->     JSON_STORAGE_SIZE(jcol) AS Size
    -> FROM jtable;
+-----------------------------------------------+------+
| jcol                                          | Size |
+-----------------------------------------------+------+
| {"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"} |   47 |
+-----------------------------------------------+------+
1 row in set (0.00 sec)

根据JSON_STORAGE_SIZE()的输出,插入到该列中的 JSON 文档占用 47 个字节。更新后,该函数将显示用于新设置值的存储:

mysql> UPDATE jtable
mysql>     SET jcol = '{"a": 4.55, "b": "wxyz", "c": "[true, false]"}';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT
    ->     jcol,
    ->     JSON_STORAGE_SIZE(jcol) AS Size
    -> FROM jtable;
+------------------------------------------------+------+
| jcol                                           | Size |
+------------------------------------------------+------+
| {"a": 4.55, "b": "wxyz", "c": "[true, false]"} |   56 |
+------------------------------------------------+------+
1 row in set (0.00 sec)

此函数还显示当前用于在用户变量中存储 JSON 文档的空间:

mysql> SET @j = '[100, "sakila", [1, 3, 5], 425.05]';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+------------------------------------+------+
| @j                                 | Size |
+------------------------------------+------+
| [100, "sakila", [1, 3, 5], 425.05] |   45 |
+------------------------------------+------+
1 row in set (0.00 sec)

mysql> SET @j = JSON_SET(@j, '$[1]', "json");
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+----------------------------------+------+
| @j                               | Size |
+----------------------------------+------+
| [100, "json", [1, 3, 5], 425.05] |   43 |
+----------------------------------+------+
1 row in set (0.00 sec)

mysql> SET @j = JSON_SET(@j, '$[2][0]', JSON_ARRAY(10, 20, 30));
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+---------------------------------------------+------+
| @j                                          | Size |
+---------------------------------------------+------+
| [100, "json", [[10, 20, 30], 3, 5], 425.05] |   56 |
+---------------------------------------------+------+
1 row in set (0.00 sec)

对于 JSONLiterals,此函数还返回当前使用的存储空间,如下所示:

mysql> SELECT
    ->     JSON_STORAGE_SIZE('[100, "sakila", [1, 3, 5], 425.05]') AS A,
    ->     JSON_STORAGE_SIZE('{"a": 1000, "b": "a", "c": "[1, 3, 5, 7]"}') AS B,
    ->     JSON_STORAGE_SIZE('{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}') AS C,
    ->     JSON_STORAGE_SIZE('[100, "json", [[10, 20, 30], 3, 5], 425.05]') AS D;
+----+----+----+----+
| A  | B  | C  | D  |
+----+----+----+----+
| 45 | 44 | 47 | 56 |
+----+----+----+----+
1 row in set (0.00 sec)

此功能已在 MySQL 5.7.22 中添加。