Загрузка JSON
Ниже приведены очень простые примеры загрузки структурированных и полуструктурированных данных в формате JSON. Для более сложного JSON, включая вложенные структуры, см. руководство Проектирование схемы JSON.
Загрузка структурированного JSON
В этом разделе предполагается, что данные находятся в формате NDJSON (Newline delimited JSON — JSON, где объекты разделены переводами строки), который в ClickHouse известен как JSONEachRow, и хорошо структурированы, то есть имена и типы столбцов фиксированы. Формат NDJSON является предпочтительным для загрузки JSON из‑за своей компактности и эффективного использования места, но поддерживаются и другие форматы как для ввода, так и вывода.
Рассмотрим следующий пример JSON, представляющий строку из набора данных Python PyPI:
Чтобы загрузить этот JSON-объект в ClickHouse, необходимо определить схему таблицы.
В этом простом случае наша структура статична, имена столбцов известны, а их типы чётко определены.
Хотя ClickHouse и поддерживает полуструктурированные данные через тип JSON, где имена ключей и их типы могут быть динамическими, здесь в этом нет необходимости.
В случаях, когда ваши столбцы имеют фиксированные имена и типы, и не ожидается появление новых столбцов, в продуктивной среде всегда следует предпочитать статически определённую схему.
Тип JSON предпочтителен для очень динамичных данных, где имена и типы столбцов часто меняются. Этот тип также полезен для прототипирования и исследования данных.
Простая схема для этого показана ниже, где ключи JSON сопоставляются с именами столбцов:
Здесь мы выбрали ключ сортировки с помощью оператора ORDER BY. Дополнительные сведения о ключах сортировки и о том, как их выбирать, см. здесь.
ClickHouse может загружать JSON-данные в нескольких форматах, автоматически определяя тип по расширению и содержимому. Мы можем читать JSON-файлы для указанной выше таблицы с помощью функции S3:
Обратите внимание, что нам не нужно явно указывать формат файла. Вместо этого мы используем glob‑шаблон, чтобы прочитать все файлы *.json.gz в бакете. ClickHouse автоматически определяет, что формат — JSONEachRow (ndjson), по расширению и содержимому файла. Формат можно указать вручную в параметрах функции на случай, если ClickHouse не сможет определить его автоматически.
Указанные выше файлы также сжаты. ClickHouse автоматически определяет и обрабатывает их.
Чтобы загрузить строки из этих файлов, мы можем использовать INSERT INTO SELECT:
Строки также можно загружать непосредственно в запросе с помощью предложения FORMAT, например:
В этих примерах предполагается использование формата JSONEachRow. Также поддерживаются другие распространённые форматы JSON, примеры их загрузки приведены здесь.
Загрузка полуструктурированного JSON
В нашем предыдущем примере загружался JSON, который был статичным, с заранее известными именами ключей и типами. На практике так бывает не всегда — ключи могут добавляться, а их типы меняться. Это типично для сценариев, таких как данные обсервабилити.
ClickHouse обрабатывает такие случаи с помощью специального типа JSON.
Рассмотрим следующий пример из расширенной версии вышеупомянутого набора данных Python PyPI dataset. Здесь мы добавили произвольный столбец tags со случайными парами ключ–значение.
Столбец tags здесь непредсказуем и поэтому его невозможно смоделировать в схеме данных. Чтобы загрузить эти данные, мы можем использовать нашу предыдущую схему, но добавить дополнительный столбец tags типа JSON:
Заполним таблицу тем же способом, что и исходный набор данных:
Обратите внимание на разницу в производительности при загрузке данных. Для JSON-столбца при вставке требуется определение типов, а также дополнительное место для хранения, если есть столбцы, содержащие значения более чем одного типа. Хотя тип JSON можно настроить (см. Проектирование схемы JSON) так, чтобы его производительность была сопоставима с явным объявлением столбцов, по умолчанию он намеренно остаётся гибким. Однако эта гибкость имеет свою цену.
Когда использовать тип JSON
Используйте тип JSON, когда ваши данные:
- Имеют непредсказуемые ключи, которые могут меняться со временем.
- Содержат значения с различными типами (например, путь может иногда содержать строку, а иногда число).
- Требуют гибкости схемы, когда строгая типизация невозможна.
Если структура ваших данных известна и стабильна, необходимость в типе JSON возникает редко, даже если ваши данные находятся в формате JSON. В частности, если ваши данные имеют:
- Плоскую структуру с известными ключами: используйте стандартные типы столбцов, например String.
- Предсказуемую вложенность: используйте типы Tuple, Array или Nested для таких структур.
- Предсказуемую структуру с различающимися типами значений: рассмотрите вместо этого использование типов Dynamic или Variant.
Вы также можете комбинировать подходы, как мы сделали в приведённом выше примере, используя статические столбцы для предсказуемых ключей верхнего уровня и один JSON-столбец для динамической части данных.