SQLinfo.ru - Все о MySQL

Релиз JSON Labs: JSON-функции, Часть 1 — Обработка JSON-данных.

Дата: 5.05.2016

Автор: Даниил Каменский , dkamenskiy (at) yandex (dot) ru

Данная статья является переводом статьи Рика Хиллегаса про использование типа JSON, введенного в MySQL версии 5.7.7.

В релизе MySQL 5.7.7 JSON Lab добавлен встроенный тип данных JSON. Для получения большей информации об этом типе читайте блог Кнута Андреса. В текущем релизе мы также добавили несколько функций для создания и работы с JSON-документами. В этой статье мы рассмотрим следующие новые функции для работы с JSON-документами:

  • json_array()
  • json_object()
  • json_insert()
  • json_remove()
  • json_set()
  • json_replace()
  • json_append()
  • json_merge()
  • json_extract()

В посте Дага Ванвика приведен обзор функций для выборки и поиска данных в JSON-документе.

Более подробную информацию обо всех новых JSON-функциях можно найти в спецификации высокого уровня, прикрепленной к WL#7909.

Создание данных в формате JSON

Давайте начнем с создания простых JSON-данных. Предположим, мы используем тип данных JSON для хранения большого количества данных о температуре, получаемых с "умных" термостатов. Мы могли бы счесть полезными следующие таблицы:

mysql> create table thermostat_model(model_id varchar(50) primary key, capabilities json);
Query OK, 0 rows affected (0.21 sec)

mysql> create table thermostat_reading( reading json );
Query OK, 0 rows affected (0.22 sec)

Представим, что в столбце `capabilities` содержится массив тэгов. Давайте создадим один из этих массивов, используя новую функцию JSON_ARRAY(). Эта функция вычисляет список выражений переменной длины и последовательно вставляет их в JSON-массив.

mysql> select json_array( 'programmable','fan', 'ac', 'furnace' ) json_array;
+------------------------------------------+
| json_array                               |
+------------------------------------------+
| ["programmable", "fan", "ac", "furnace"] |
+------------------------------------------+
1 row in set (0.04 sec)

Это просто. В качестве альтернативы, мы могли бы просто вставить текст в столбец JSON. MySQL проанализирует текст запроса и преобразует его во встроенный двоичный формат хранения данных JSON:

mysql> insert into thermostat_model values ( 'xyzzy', '[ "programmable","fan", "ac", "furnace" ]' ), ( 'abc123', '[ "fan", "furnace" ]' );
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from thermostat_model;
+----------+------------------------------------------+
| model_id | capabilities                             |
+----------+------------------------------------------+
| abc123   | ["fan", "furnace"]                       |
| xyzzy    | ["programmable", "fan", "ac", "furnace"] |
+----------+------------------------------------------+
2 rows in set (0.00 sec)

В дополнение к JSON_ARRAY(), так же существует функция-конструктор JSON_OBJECT(). Как можно догадаться, функция JSON_OBJECT() конструирует JSON-объекты из списка пар ключ/значение. Пример:

mysql> select json_object('device_id', 3001,'unixtime', 1428440461,'setting', 64.0,'current_temp', 62.05) json_object;
+-------------------------------------------------------------------------------------+
| json_object                                                                         |
+-------------------------------------------------------------------------------------+
| {"setting": 64.0, "unixtime": 1428440461, "device_id": 3001, "current_temp": 62.05} |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
И снова, в качестве альтернативы, мы можем положить json-текст в таблицу показаний термостата.
mysql> insert into thermostat_reading values
( '{ "device_id": 3001, "unixtime": 1428462061, "setting": 69.0, "current_temp": 62.05 }' ),
( '{ "device_id": 3001, "unixtime": 1428483661, "setting": 64.0, "current_temp": 70.25 }' ),
( '{ "device_id": 3002, "unixtime": 1428462061, "setting": 68.0, "current_temp": 61.05 }' ),
( '{ "device_id": 3002, "unixtime": 1428483661, "setting": 62.0, "current_temp": 71.25 }' );
Query OK, 4 rows affected (0.05 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from thermostat_reading;
+-----------------------------------------------------------------------------------+
| reading                                                                           |
+-----------------------------------------------------------------------------------+
| {"setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05} |
| {"setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25} |
| {"setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05} |
| {"setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25} |
+-----------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

Развитие схемы: добавляем данные

Конечно, в реальном мире данные меняются со временем, так же как и использующее их приложение. Предположим, что мы, производители термостатов, не можем сказать включены ли они, и выполняют ли они на самом деле свою работу. Скажем, мы удаленно доработали все наши термостаты таким образом, что теперь они стали передавать свое состояние “включен/выключен”. Постепенно наша таблица показаний термостатов будет содержать как старые записи, без информации о состоянии, так и новые (с информацией):

mysql> insert into thermostat_reading values
( '{"on": true, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}' ),
( '{"on": false, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25}' ),
( '{"on": true, "setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05}' ),
( '{"on": false, "setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25}' );
Query OK, 4 rows affected (0.03 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> select * from thermostat_reading;
+------------------------------------------------------------------------------------------------+
| reading                                                                                        |
+------------------------------------------------------------------------------------------------+
| {"setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05}              |
| {"setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}              |
| {"setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05}              |
| {"setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25}              |
| {"on": true, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}  |
| {"on": false, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |
| {"on": true, "setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05}  |
| {"on": false, "setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25} |
+------------------------------------------------------------------------------------------------+
8 rows in set (0.00 sec)

Теперь мы хотим исправить все старые записи таким образом, чтобы они тоже содержали состояние “включен/выключен”. Для наших целей достаточно, чтобы в старых записях состояние равнялось NULL (это будет означать “неизвестное” состояние). Для этого мы можем использовать новую функцию JSON_INSERT(). JSON_INSERT() добавляет недостающую информацию в документы JSON. Однако, при этом она не перепишет данные, которые уже там хранятся. JSON_INSERT() принимает 3 аргумента: изменяемый документ; путь (см. ниже) определяющий изменяемую часть документа и значение вставляемое в изменяемую часть:

mysql> update thermostat_reading set reading = json_insert( reading, '$.on', cast( 'null' as json ) );
Query OK, 4 rows affected (0.05 sec)
Rows matched: 8  Changed: 4  Warnings: 0
 
mysql> select * from thermostat_reading;
+------------------------------------------------------------------------------------------------+
| reading                                                                                        |
+------------------------------------------------------------------------------------------------+
| {"on": null, "setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05}  |
| {"on": null, "setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}  |
| {"on": null, "setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05}  |
| {"on": null, "setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25}  |
| {"on": true, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}  |
| {"on": false, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |
| {"on": true, "setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05}  |
| {"on": false, "setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25} |
+------------------------------------------------------------------------------------------------+
8 rows in set (0.00 sec)

Обратите внимание, что в старых рядах нет информации о том каким было состояние “включен/выключен” (значение NULL). Так же обратите внимание, что новые ряды не изменились.

При более внимательном взгляде на выражение UPDATE вы могли бы поинтересоваться:

  1. Что это за странный аргумент ‘$.on‘?
  2. Почему небходимо преобразовывать (CAST) NULL в JSON?

Сперва поговорим об аргументе ‘$.on‘. Это путь. Это - адрес назначения внутри документа JSON. Путь начинается с символа $, который означает корень пути. Во всех новых функциях работы с JSON, корень всегда обозначается как $, и это всегда значит "текущий документ". После $ идет произвольно длинная последовательность имен членов и индексов массива, которая приводит нас к значению внутри документа. Имена членов указываются точкой (“.”)и именем ключа. Индексы массива это просто номера, заключенные в квадратные скoбки. Например, путь $.fred.children[3] означает “Третий потомок узла ‘fred’ в текущем документе”. Не беспокойтесь пока об этом. Все пути в этой статье очень простые. Например, в нашем вырaжении UPDATE, приведенном выше, $.on означает "Член ‘on’ текущего документа".

Хорошо, а что с этим преобразованием CAST? Без него аргумент NULL вызовет приведение всего выражения JSON_INSERT() к NULL. А это ударит по старым рядам. Более того, CAST(NULL AS JSON) вызовет такой же эффект. Проблема в том, что есть разница между литералом null в JSON и в SQL. Что бы создать литерал null для JSON используйте CAST для преобразования некоторого JSON-текста, который содержит только литерал null.

Не волнуйтесь, если это сейчас кажется сложным. Как только вы попробуете новые функций для работы с JSON, вы быстро научитесь как обращаться с null-литералами JSON. В оставшейся части статьи нам не придется иметь дела с NULL из SQL.

Развитие схемы: удаление данных

Раз уж вы добавляете данные, вам понадобится возможность удалить их впоследствии. Предположим что мы, производители термостатов, решили, что добавить состояние "включен/выключен" было плохой идеей. Нам снова потребуется удаленно доработать все наши термостаты. Мы заставим их не сообщать свое состояние. После этого, мы хотим удалить все эти ненужные данные о состоянии из наших старых показаний термостатов. Для этого мы используем новую функцию JSON_REMOVE(). JSON_REMOVE() принимает в качестве аргумента догумент, а так же путь к удаляемым данным. Вот так мы удалим все записи о состоянии "включен/выключен":

mysql> update thermostat_reading set reading = json_remove( reading, '$.on' );
Query OK, 8 rows affected (0.03 sec)
Rows matched: 8  Changed: 8  Warnings: 0
 
mysql> select * from thermostat_reading;
+-----------------------------------------------------------------------------------+
| reading                                                                           |
+-----------------------------------------------------------------------------------+
| {"setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05} |
| {"setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25} |
| {"setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05} |
| {"setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25} |
| {"setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05} |
| {"setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |
| {"setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05} |
| {"setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25} |
+-----------------------------------------------------------------------------------+
8 rows in set (0.00 sec)

Развитие схемы: обновление данных

Предположим что мы, производители термостатов, доработали их так, чтобы они содержали новые данные, "спред" или разницу между настройкой термостата и фактической температурой в комнате. Более новые записи будут содержать эти данные, но старые - нет:

mysql> insert into thermostat_reading values
( '{"spread": 3.95, "setting": 69, "unixtime": 1428634861, "device_id": 3001, "current_temp": 65.05}' ),
( '{"spread": -12.25, "setting": 64, "unixtime": 1428656461, "device_id": 3001, "current_temp": 76.25}' ),
( '{"spread": 1.95, "setting": 68, "unixtime": 1428634861, "device_id": 3002, "current_temp": 66.05}' ),
( '{"spread": -15.25, "setting": 62, "unixtime": 1428656461, "device_id": 3002, "current_temp": 77.25}' );
Query OK, 4 rows affected (0.03 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> select * from thermostat_reading;  
+---------------------------------------------------------------------------------------------------------+
| reading                                                                                                 |
+---------------------------------------------------------------------------------------------------------+
| {"setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05}                       |
| {"setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}                       |
| {"setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05}                       |
| {"setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25}                       |
| {"setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}                       |
| {"setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25}                       |
| {"setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05}                       |
| {"setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25}                       |
| {"spread": 3.95, "setting": 69, "unixtime": 1428634861, "device_id": 3001, "current_temp": 65.05}       |
| {"spread": -12.25, "setting": 64, "unixtime": 1428656461, "device_id": 3001, "current_temp": 76.25}     |
| {"spread": 1.95, "setting": 68, "unixtime": 1428634861, "device_id": 3002, "current_temp": 66.05}       |
| {"spread": -15.25, "setting": 62, "unixtime": 1428656461, "device_id": 3002, "current_temp": 77.25}     |
+---------------------------------------------------------------------------------------------------------+
12 rows in set (0.00 sec)

Мы можем использовать фкнцию JSON_SET() чтобы обновить старые данные. JSON_SET() ведет себя очень похоже на JSON_INSERT(), помимо того, что она переписывает существующие значения:

mysql> update thermostat_reading set reading = json_set
(
    reading,
    '$.spread',
    cast( json_extract( reading, '$.current_temp' ) as decimal(5,2) ) - cast( json_extract( reading, '$.setting' ) as decimal(5,2) )
);
Query OK, 12 rows affected (0.04 sec)
Rows matched: 12  Changed: 12  Warnings: 0
 
mysql> select * from thermostat_reading;
+----------------------------------------------------------------------------------------------------+
| reading                                                                                            |
+----------------------------------------------------------------------------------------------------+
| {"spread": -6.95, "setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05} |
| {"spread": 6.25, "setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}  |
| {"spread": -6.95, "setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05} |
| {"spread": 9.25, "setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25}  |
| {"spread": -6.95, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05} |
| {"spread": 11.25, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |
| {"spread": -6.95, "setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05} |
| {"spread": 14.25, "setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25} |
| {"spread": -3.95, "setting": 69, "unixtime": 1428634861, "device_id": 3001, "current_temp": 65.05} |
| {"spread": 12.25, "setting": 64, "unixtime": 1428656461, "device_id": 3001, "current_temp": 76.25} |
| {"spread": -1.95, "setting": 68, "unixtime": 1428634861, "device_id": 3002, "current_temp": 66.05} |
| {"spread": 15.25, "setting": 62, "unixtime": 1428656461, "device_id": 3002, "current_temp": 77.25} |
+----------------------------------------------------------------------------------------------------+
12 rows in set (0.00 sec)

Обратите внимание, что значения "спреда" добавлены к записям, у которых их раньше не было. И мы обновили существующие значения "спреда". Упс! Мы же не собирались этого делать! У нас получилось вычисление в обратном направлении. Мы собирались вычислить спред иначе, таким же путем как его вычисляет термостат, а именно вычитанием фактической температуры от заданной на термостате. Это не проблема. Мы исправим это за долю секунды. Прежде чем мы это сделаем, вас возможно заинтересовала функция которую мы только что использовали - JSON_EXTRACT(). JSON_EXTRACT() возвращает значение из документа JSON. Она находит его по указанному пути.

Хорошо, а теперь давайте исправим наши данные с термостатов. Для этой задачи мы используем другую изменяющую функцию - JSON_REPLACE(). JSON_REPLACE() ведет себя как противоположность JSON_INSERT(): она не затрагивает записи в которых отсутствуют нужные данные. JSON_REPLACE() изменяет только те записи, в которых эти данные есть:

mysql> update thermostat_reading set reading = json_replace
(
    reading,
    '$.spread',
    cast( json_extract( reading, '$.setting' ) as decimal(5,2) ) - cast( json_extract( reading, '$.current_temp' ) as decimal(5,2) )
);
Query OK, 12 rows affected (0.04 sec)
Rows matched: 12  Changed: 12  Warnings: 0
 
mysql> select * from thermostat_reading;
+-----------------------------------------------------------------------------------------------------+
| reading                                                                                                 |
+-----------------------------------------------------------------------------------------------------+
| {"spread": 6.95, "setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05}   |
| {"spread": -6.25, "setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}  |
| {"spread": 6.95, "setting": 68, "unixtime": 1428462061, "device_id": 3002, "current_temp": 61.05}   |
| {"spread": -9.25, "setting": 62, "unixtime": 1428483661, "device_id": 3002, "current_temp": 71.25}  |
| {"spread": 6.95, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}   |
| {"spread": -11.25, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |
| {"spread": 6.95, "setting": 68, "unixtime": 1428548461, "device_id": 3002, "current_temp": 61.05}   |
| {"spread": -14.25, "setting": 62, "unixtime": 1428570061, "device_id": 3002, "current_temp": 76.25} |
| {"spread": 3.95, "setting": 69, "unixtime": 1428634861, "device_id": 3001, "current_temp": 65.05}   |
| {"spread": -12.25, "setting": 64, "unixtime": 1428656461, "device_id": 3001, "current_temp": 76.25} |
| {"spread": 1.95, "setting": 68, "unixtime": 1428634861, "device_id": 3002, "current_temp": 66.05}   |
| {"spread": -15.25, "setting": 62, "unixtime": 1428656461, "device_id": 3002, "current_temp": 77.25} |
+-----------------------------------------------------------------------------------------------------+
12 rows in set (0.00 sec)

Развитие схемы: дополнение данных

Предположим теперь, что нам нужно дополнить старые данные новыми, а не полностью изменить их. Представим что мы, производители термостатов, доработали их. В некоторые модели мы добавили контроль скорости вращения вентилятора. После этой доработки нам нужно отразить новую возможность в метаданных наших термостатов. Мы можем воспользоваться функцикей JSON_ARRAY_APPEND() (до версии 5.7.9 функция называлась JSON_APPEND). JSON_ARRAY_APPEND() добавляет значение в конец массива:

mysql> update thermostat_model set capabilities = json_append( capabilities, '$', 'smart_fan' ) where model_id = 'xyzzy';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql> select * from thermostat_model;
+----------+-------------------------------------------------------+
| model_id | capabilities                                          |
+----------+-------------------------------------------------------+
| abc123   | ["fan", "furnace"]                                    |
| xyzzy    | ["programmable", "fan", "ac", "furnace", "smart_fan"] |
+----------+-------------------------------------------------------+
2 rows in set (0.00 sec)

Теперь представьте, что еще мы дополнили некоторые из наших моделей пакетом из нескольких элементов безопасности. Давайте используем новую функцию JSON_MERGE(), чтобы соответствующим образом обновить нашим метаданные. JSON_MERGE() - это очень мощная функция. Она может соединить два массива вместе, и это как раз то, что мы собираемся сделать. Она так же может соединить два объека вместе - член за членом, уровень за уровнем. JSON_MERGE() принимает в качестве аргументов произвольной длины список JSON-документов и объединяет их в один составной документ:

mysql> update thermostat_model
    set capabilities = json_merge( capabilities, json_array( 'https', 'password_protected', 'intrusion_detection' ) )
    where model_id = 'xyzzy';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql> select * from thermostat_model;
+----------+-------------------------------------------------------------------------------------------------------------+
| model_id | capabilities                                                                                                |
+----------+-------------------------------------------------------------------------------------------------------------+
| abc123   | ["fan", "furnace"]                                                                                          |
| xyzzy    | ["programmable", "fan", "ac", "furnace", "smart_fan", "https", "password_protected", "intrusion_detection"] |
+----------+-------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Развитие схемы: индексация JSON-данных

Мы начали с сохранения данных с термостатов в одну кучу. Некоторое время спустя, мы хотим получить эти записи. Нам нужен полезный индекс. Давайте добавим виртуальную колонку в таблицу записей с термостатов и проиндексируем ее. Это поможет нам быстро находить показания термостата на основе его уникального идентификатора:

mysql> alter table thermostat_reading
    add column device_id int generated always as ( json_extract( reading, '$.device_id' ) ) virtual;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
mysql> create index tr_di on thermostat_reading( device_id );
Query OK, 12 rows affected (0.57 sec)
Records: 12  Duplicates: 0  Warnings: 0
 
mysql> select * from thermostat_reading where device_id = 3001;
+-----------------------------------------------------------------------------------------------------+-----------+
| reading                                                                                             | device_id |
+-----------------------------------------------------------------------------------------------------+-----------+
| {"spread": 6.95, "setting": 69, "unixtime": 1428462061, "device_id": 3001, "current_temp": 62.05}   |      3001 |
| {"spread": -6.25, "setting": 64, "unixtime": 1428483661, "device_id": 3001, "current_temp": 70.25}  |      3001 |
| {"spread": 6.95, "setting": 69, "unixtime": 1428548461, "device_id": 3001, "current_temp": 62.05}   |      3001 |
| {"spread": -11.25, "setting": 64, "unixtime": 1428570061, "device_id": 3001, "current_temp": 75.25} |      3001 |
| {"spread": 3.95, "setting": 69, "unixtime": 1428634861, "device_id": 3001, "current_temp": 65.05}   |      3001 |
| {"spread": -12.25, "setting": 64, "unixtime": 1428656461, "device_id": 3001, "current_temp": 76.25} |      3001 |
+-----------------------------------------------------------------------------------------------------+-----------+
6 rows in set (0.00 sec)
 
mysql> explain format=JSON select * from thermostat_reading where device_id = 3001\G
*************************** 1. row ***************************
EXPLAIN: {
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "1.44"
    },
    "table": {
      "table_name": "thermostat_reading",
      "access_type": "ref",
      "possible_keys": [
        "tr_di"
      ],
      "key": "tr_di",
      "used_key_parts": [
        "device_id"
      ],
      "key_length": "5",
      "ref": [
        "const"
      ],
      "rows_examined_per_scan": 1,
      "rows_produced_per_join": 1,
      "filtered": "100.00",
      "cost_info": {
        "read_cost": "1.20",
        "eval_cost": "0.24",
        "prefix_cost": "1.44",
        "data_read_per_join": "28"
      },
      "used_columns": [
        "reading",
        "device_id"
      ]
    }
  }
}
1 row in set, 1 warning (0.00 sec)

Пожалуйста, ознакомьтесь со статьей Джимми Йенга для более детальной информации о новом “функциональном индексе”, который так же был добавлен в релиз MySQL 5.7.7 JSON Lab. Теперь вы готовы к тому чтобы создавать и работать с данным в формате JSON! Призываем вас прочесть статью Дага Ванвика по этой теме. Она описывает новые функции выборки и поиска, связанные с JSON и добавленные в MySQL 5.7.7 JSON Lab, а именно:

  • json_search()
  • json_contains()
  • json_contains_path()
  • json_valid()
  • json_type()
  • json_keys()
  • json_length()
  • json_depth()
  • json_unquote()
  • json_quote()

Пожалуйста, дайте нам знать, что Вы думаете о новых возможностях для работы с JSON! Мы хотели бы получить от вас пожелания о том, что еще бы вы хотели увидеть в связи с расширением поддержки JSON. Если вы столкнулись с проблемами при использовании этих новых возможностей, дайте нам знать в комментариях, сообщите о проблеме здесь или здесь.

Дата публикации: 5.05.2016

© Все права на данную статью принадлежат порталу SQLInfo.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в бумажных изданиях допускается только с разрешения редакции.

Статьи :
 Установка и настройка MySQL
 Коды ошибок в MySQL
 Программирование в MySQL
 Оптимизация производительности
 Кодировка символов в MySQL
>Хранение данных в MySQL
 MySQL Cluster
См. также:
 Оптимизация производительности MySQL
 Услуги по оптимизации MySQL