14.17.8 Функции для работы с JSON
В этом разделе описаны служебные функции, которые работают с JSON-значениями или строками, которые могут быть распарсены как JSON-значения. JSON_PRETTY() выводит JSON-значение в формате, удобном для чтения. JSON_STORAGE_SIZE() и JSON_STORAGE_FREE() соответственно показывают объем занимаемого места в памяти заданным JSON-значением и объем свободного места в JSON столбце после частичного обновления.
-
Обеспечивает форматированный вывод JSON-значений, аналогично тому, как это реализовано в PHP и других языках и системах баз данных. Предоставляемое значение должно быть JSON-значением или корректным строковым представлением JSON-значения. Излишние пробелы и новые строки в этом значении не влияют на вывод. Для
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" ] -
Для значения столбца
JSONэта функция показывает, сколько места в памяти было освобождено в его двоичном представлении после его обновления на месте с помощьюJSON_SET(),JSON_REPLACE()илиJSON_REMOVE(). Аргумент также может быть корректным JSON-документом или строкой, которую можно распарсить как таковой — как буквальное значение, так и значение пользовательской переменной — в этом случае функция возвращает 0. Функция возвращает положительное, ненулевое значение, если аргумент является значениемJSONстолбца, который был обновлён, как описано ранее, таким образом, что его двоичное представление занимает меньше места, чем до обновления. ДляJSONстолбца, который был обновлён таким образом, что его двоичное представление равно или больше, чем раньше, или если обновление не смогло воспользоваться частичным обновлением, она возвращает 0; она возвращаетNULL, если аргумент являетсяNULL.Если
json_valнеNULL, и не является ни корректным JSON-документом, ни может быть успешно распарсено как таковой, возникает ошибка.В этом примере мы создаём таблицу, содержащую
JSONстолбец, затем вставляем строку, содержащую JSON-объект:mysql>
CREATE TABLE jtable (jcol JSON);Query OK, 0 rows affected (0.38 sec) mysql>INSERT INTO jtable VALUES->('{"a": 10, "b": "wxyz", "c": "[true, false]"}');Query OK, 1 row affected (0.04 sec) mysql>SELECT * FROM jtable;+----------------------------------------------+ | jcol | +----------------------------------------------+ | {"a": 10, "b": "wxyz", "c": "[true, false]"} | +----------------------------------------------+ 1 row in set (0.00 sec)Теперь мы обновляем значение столбца, используя
JSON_SET()таким образом, что может быть выполнено частичное обновление; в данном случае, мы заменяем значение, на которое указываетcключ (массив[true, false]), на значение, занимающее меньше места (целое число1):mysql>
UPDATE jtable->SET jcol = JSON_SET(jcol, "$.a", 10, "$.b", "wxyz", "$.c", 1);Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT * FROM jtable;+--------------------------------+ | jcol | +--------------------------------+ | {"a": 10, "b": "wxyz", "c": 1} | +--------------------------------+ 1 row in set (0.00 sec) mysql>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;+-------------------------+ | JSON_STORAGE_FREE(jcol) | +-------------------------+ | 14 | +-------------------------+ 1 row in set (0.00 sec)Эффекты последовательных частичных обновлений на это свободное место являются кумулятивными, как показано в этом примере, использующем
JSON_SET(), чтобы уменьшить место, занимаемое значением с ключомb(и не внося других изменений):mysql>
UPDATE jtable->SET jcol = JSON_SET(jcol, "$.a", 10, "$.b", "wx", "$.c", 1);Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;+-------------------------+ | JSON_STORAGE_FREE(jcol) | +-------------------------+ | 16 | +-------------------------+ 1 row in set (0.00 sec)Обновление столбца без использования
JSON_SET(),JSON_REPLACE()илиJSON_REMOVE()означает, что оптимизатор не может выполнить обновление на месте; в этом случаеJSON_STORAGE_FREE()возвращает 0, как показано здесь:mysql>
UPDATE jtable SET jcol = '{"a": 10, "b": 1}';Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;+-------------------------+ | JSON_STORAGE_FREE(jcol) | +-------------------------+ | 0 | +-------------------------+ 1 row in set (0.00 sec)Частичные обновления JSON-документов могут быть выполнены только для значений столбцов. Для пользовательской переменной, хранящей JSON-значение, значение всегда полностью заменяется, даже когда обновление выполняется с помощью
JSON_SET():mysql>
SET @j = '{"a": 10, "b": "wxyz", "c": "[true, false]"}';Query OK, 0 rows affected (0.00 sec) mysql>SET @j = JSON_SET(@j, '$.a', 10, '$.b', 'wxyz', '$.c', '1');Query OK, 0 rows affected (0.00 sec) mysql>SELECT @j, JSON_STORAGE_FREE(@j) AS Free;+----------------------------------+------+ | @j | Free | +----------------------------------+------+ | {"a": 10, "b": "wxyz", "c": "1"} | 0 | +----------------------------------+------+ 1 row in set (0.00 sec)Для JSON-литерала эта функция всегда возвращает 0:
mysql>
SELECT JSON_STORAGE_FREE('{"a": 10, "b": "wxyz", "c": "1"}') AS Free;+------+ | Free | +------+ | 0 | +------+ 1 row in set (0.00 sec) -
Эта функция возвращает количество байтов, используемых для хранения двоичного представления JSON-документа. Когда аргументом является
JSONстолбец, это место, используемое для хранения JSON-документа, как он был вставлен в столбец, до любых частичных обновлений, которые могли быть выполнены на нем позже.json_valдолжен быть корректным JSON-документом или строкой, которая может быть распарсена как таковой. В случае, если это строка, функция возвращает количество места в памяти в двоичном представлении JSON, которое создается при парсинге строки как JSON и преобразовании ее в двоичный вид. Она возвращаетNULL, если аргумент являетсяNULL.Возникает ошибка, когда
json_valнеNULLи не является — или не может быть успешно распарсен как — JSON-документом.Чтобы проиллюстрировать поведение этой функции, когда она используется со
JSONстолбцом в качестве аргумента, мы создаём таблицу с именемjtable, содержащуюJSONстолбецjcol, вставляем 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,->JSON_STORAGE_FREE(jcol) AS Free->FROM jtable;+-----------------------------------------------+------+------+ | jcol | Size | Free | +-----------------------------------------------+------+------+ | {"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"} | 47 | 0 | +-----------------------------------------------+------+------+ 1 row in set (0.00 sec)Согласно выводу
JSON_STORAGE_SIZE(), JSON-документ, вставленный в столбец, занимает 47 байтов. Мы также проверили количество памяти, освобожденной любыми предыдущими частичными обновлениями столбца, используяJSON_STORAGE_FREE(); поскольку никаких обновлений ещё не было выполнено, это 0, как ожидалось.Далее мы выполним
UPDATEнад таблицей, которая должна привести к частичному обновлению документа, хранящегося вjcol, и затем проверим результат, как показано здесь:mysql>
UPDATE jtable SET jcol =->JSON_SET(jcol, "$.b", "a");Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT->jcol,->JSON_STORAGE_SIZE(jcol) AS Size,->JSON_STORAGE_FREE(jcol) AS Free->FROM jtable;+--------------------------------------------+------+------+ | jcol | Size | Free | +--------------------------------------------+------+------+ | {"a": 1000, "b": "a", "c": "[1, 3, 5, 7]"} | 47 | 3 | +--------------------------------------------+------+------+ 1 row in set (0.00 sec)Значение, возвращаемое
JSON_STORAGE_FREE()в предыдущем запросе, указывает, что было выполнено частичное обновление JSON-документа, и что это освободило 3 байта памяти, используемой для его хранения. Результат, возвращаемыйJSON_STORAGE_SIZE(), не изменяется частичным обновлением.Частичные обновления поддерживаются для обновлений с помощью
JSON_SET(),JSON_REPLACE()илиJSON_REMOVE(). Прямая присваивание значенияJSONстолбцу не может быть частично обновлено; после такого обновленияJSON_STORAGE_SIZE()всегда показывает место, используемое для нового значения:mysql>
UPDATE jtablemysql>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,->JSON_STORAGE_FREE(jcol) AS Free->FROM jtable;+------------------------------------------------+------+------+ | jcol | Size | Free | +------------------------------------------------+------+------+ | {"a": 4.55, "b": "wxyz", "c": "[true, false]"} | 56 | 0 | +------------------------------------------------+------+------+ 1 row in set (0.00 sec)Пользовательская переменная JSON не может быть частично обновлена. Это означает, что эта функция всегда показывает место, которое в настоящее время используется для хранения 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)Для JSON-литерала эта функция всегда возвращает текущее занимаемое место:
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)
© 2025 Oracle
Licensed under the GPLv2 License.