Когда использовать тип JSON
JSON предназначен для запросов, фильтрации и агрегации по отдельным полям в объектах JSON с динамической или непредсказуемой структурой. Для этого объекты JSON разбиваются на отдельные подстолбцы, что значительно уменьшает объём читаемых данных и ускоряет запросы по выбранным полям по сравнению с такими альтернативами, как Map или разбор строк.
Однако у этого подхода есть важные недостатки:
- Более медленные
INSERT- Разбиение JSON на подстолбцы, определение типов и управление гибкими структурами хранения делают вставку медленнее по сравнению с хранением JSON в виде простого столбцаString. - Медленнее при чтении объектов целиком - Если вам нужно получать JSON-документы целиком, а не отдельные поля, тип
JSONработает медленнее, чем чтение из столбцаString. Дополнительные затраты на восстановление объектов из отдельных подстолбцов не дают преимуществ, если вы не выполняете запрос по отдельным полям. - Дополнительные накладные расходы на хранение - Поддержка отдельных подстолбцов создаёт дополнительные структурные накладные расходы по сравнению с хранением JSON как одного строкового значения.
Используйте тип JSON, когда:
- У ваших данных динамическая или непредсказуемая структура, а ключи различаются от документа к документу
- Типы полей или схемы меняются со временем либо различаются между записями
- Вам нужно выполнять запросы, фильтровать или агрегировать данные по определённым путям внутри объектов JSON, структуру которых невозможно заранее предсказать
- Ваш сценарий предполагает работу с полуструктурированными данными, такими как журнал, события или пользовательский контент с непоследовательными схемами
Используйте столбец String (или структурированные типы), когда:
- Структура ваших данных известна и стабильна — в этом случае лучше использовать обычные столбцы, типы
Tuple,Array,DynamicилиVariant - Документы
JSONрассматриваются как непрозрачные blob-объекты, которые только хранятся и извлекаются целиком, без анализа на уровне полей - Вам не нужно выполнять запросы или фильтровать данные по отдельным полям JSON в базе данных
JSON— это просто формат передачи/хранения, а не формат, который анализируется в ClickHouse
Рекомендации и советы по использованию JSON
- Указывайте типы путей с помощью подсказок в определении столбца, чтобы задавать типы для известных подстолбцов и избегать лишнего вывода типов.
- Пропускайте пути, если эти значения вам не нужны, с помощью SKIP и SKIP REGEXP, чтобы сократить объём хранения и повысить производительность.
- Не задавайте
max_dynamic_pathsслишком большим — большие значения увеличивают потребление ресурсов и снижают эффективность. Как правило, держите его ниже 10 000.
Подсказки типовПодсказки типов — это не просто способ избежать лишнего вывода типов: они полностью устраняют дополнительный уровень косвенности при хранении и обработке. Пути JSON с подсказками типов всегда хранятся так же, как обычные столбцы, без необходимости использовать столбцы-дискриминаторы или выполнять динамическое разрешение во время выполнения запроса. Это означает, что при хорошо заданных подсказках типов вложенные поля JSON обеспечивают ту же производительность и эффективность, как если бы они изначально были смоделированы как поля верхнего уровня. В результате для датасетов, которые в целом однородны, но при этом выигрывают от гибкости JSON, подсказки типов позволяют сохранить производительность без необходимости перестраивать схему или конвейер приёма.
Расширенные возможности
- JSON-столбцы можно использовать в первичных ключах так же, как и любые другие столбцы. Для подстолбцов нельзя указывать кодеки.
- Они поддерживают интроспекцию с помощью таких функций, как
JSONAllPathsWithTypes()иJSONDynamicPaths(). - Вы можете читать вложенные объекты с помощью синтаксиса
.^. - Синтаксис запросов может отличаться от стандартного SQL и требовать специального приведения типов или операторов для вложенных полей.
Примеры
tags. Если бы это был просто список строк, мы могли бы представить его как Array(String), но давайте предположим, что можно добавлять произвольные структуры тегов со смешанными типами (обратите внимание, score может быть строкой или целым числом). Наш изменённый JSON-документ:
tags типа JSON. Ниже приведены оба примера:
Мы указываем подсказку типа для столбца
update_date в определении JSON, так как используем его в ключе сортировки/первичном ключе. Это помогает ClickHouse понять, что этот столбец не может быть null, и определить, какой подстолбец update_date использовать (для каждого типа их может быть несколько, поэтому иначе возникает неоднозначность).JSONAllPathsWithTypes и output format PrettyJSONEachRow:
tags. Обычно этот вариант предпочтителен, поскольку сводит к минимуму объём автоматически определяемых ClickHouse данных:
tags.