clickhouse-local или в S3 бакетах — и/или автоматически создавать схемы перед загрузкой данных в ClickHouse.
Когда использовать определение типов
- Согласованная структура — Данные, по которым вы собираетесь определять типы, содержат все интересующие вас ключи. Определение типов основано на сэмплировании данных вплоть до максимального количества строк или байтов. Данные за пределами выборки, содержащие дополнительные столбцы, будут проигнорированы, и их нельзя будет запрашивать.
- Согласованные типы — Типы данных для конкретных ключей должны быть совместимыми, то есть должна быть возможность автоматически привести один тип к другому.
Определение типов
NDJSON. В этом разделе мы рассмотрим более сложный набор данных со вложенными структурами — набор данных arXiv, содержащий 2,5 млн научных статей. Каждая строка этого набора данных, представленного в формате NDJSON, соответствует одной опубликованной научной статье. Пример строки показан ниже:
Tuple и Array.
Этот набор данных хранится в общедоступном S3 бакете по адресу s3://datasets-documentation/arxiv/arxiv.json.gz.
Как видно, приведённый выше набор данных содержит вложенные объекты JSON. Хотя схемы следует проектировать заранее и хранить их версии, автоматическое определение схемы позволяет выводить типы на основе данных. Это позволяет автоматически генерировать DDL схемы, избавляя от необходимости составлять его вручную и ускоряя процесс разработки.
Автоматическое определение форматаПомимо определения схемы, определение схемы JSON также автоматически определяет формат данных по расширению файла и его содержимому. В результате указанный выше файл автоматически распознаётся как NDJSON.
DESCRIBE показывает, какие типы будут определены.
Избегайте NULL-значенийКак видите, многие столбцы определены как Nullable. Мы не рекомендуем использовать тип Nullable, если в этом нет крайней необходимости. С помощью schema_inference_make_columns_nullable можно управлять тем, в каких случаях применяется Nullable.
String, а столбец update_date корректно распознан как Date. Столбец versions был создан как Array(Tuple(created String, version String)) для хранения списка объектов, а authors_parsed определён как Array(Array(String)) для вложенных массивов.
Управление определением типовАвтоматическим определением дат и значений даты и времени можно управлять с помощью настроек
input_format_try_infer_dates и input_format_try_infer_datetimes соответственно (обе включены по умолчанию). Определение объектов как именованных Tuple управляется настройкой input_format_json_try_infer_named_tuples_from_objects. Другие настройки, управляющие определением схемы для JSON, например автоматическое определение чисел, можно найти здесь.Запросы к JSON
Создание таблиц
CREATE AS EMPTY приводит к автоматическому определению DDL таблицы и ее созданию. При этом никакие данные не загружаются:
SHOW CREATE TABLE:
input_format_max_rows_to_read_for_schema_inference (по умолчанию 25000) и input_format_max_bytes_to_read_for_schema_inference (по умолчанию 32 MB). Если определение выполнено некорректно, вы можете указать подсказки, как описано здесь.
Создание таблиц из фрагментов
Загрузка данных из JSON
INSERT INTO SELECT:
PrettyJSONEachRow, чтобы отобразить строки в их исходной структуре:
Обработка ошибок
input_format_allow_errors_num и input_format_allow_errors_ratio, чтобы разрешить игнорирование определённого числа строк, если данные вызывают ошибки при вставке. Кроме того, для более точного определения схемы можно задать подсказки.
Работа с полуструктурированными и динамическими данными
JSON.
Если вы знаете, что ваш JSON очень динамичен, содержит много уникальных ключей и несколько типов для одних и тех же ключей, мы рекомендуем не использовать определение схемы с JSONEachRow, чтобы выводить отдельный столбец для каждого ключа, — даже если данные представлены в формате newline-delimited JSON.
Рассмотрим следующий пример из расширенной версии приведенного выше набора данных Python PyPI. Здесь мы добавили произвольный столбец tags со случайными парами «ключ — значение».
JSONEachRow. Он пытается определить тип столбца для каждого ключа в JSON — то есть фактически применить к данным статическую схему без использования типа JSON.
При тысячах уникальных столбцов такой подход работает медленно. В качестве альтернативы можно использовать формат JSONAsObject.
JSONAsObject обрабатывает весь входной поток как один объект JSON и сохраняет его в одном столбце типа JSON, поэтому он лучше подходит для сильно изменяющихся или вложенных JSON-полезных нагрузок.
sample.json со следующим JSON, где каждый объект записан с новой строки:
a как Nullable(String).
Приведение типовЭтим приведением типов можно управлять с помощью ряда настроек. Пример выше зависит от настройки
input_format_json_read_numbers_as_strings.DESCRIBE завершается ошибкой:
JSONAsObject рассматривает каждую строку как одно значение типа JSON (который позволяет одному и тому же столбцу иметь несколько типов). Это важно: