Clickhouse колоночная база данных, это значит что данные в ней хранятся не как строки, а именно буквально как колонки (можно увидеть как каждая таблица физически разделяет данные на файлы по колонкам). Эта особенность отличает Clickhouse от классических SQL баз данных вроде PosgreSQL и MySQL.
Но в то же время отличия от Clickhouse от них не так уж существенны, особенно на первый взгляд: Фактически, изменив концепцию хранения данных, поменяв местами строки с коломаками, мы остались всё с теми же таблицами. Поэтому в Clickhouse используется SQL-подобный язык, который на 90% совпадает с диалектами традиционных реляционных СУБД.
При этом Кликхаус не так уж сильно похож на другие NoSQL решения, вроде MongoDB, где для хранения данных используются пары ключ-значения, представляющие собой что-то вроде JSON структуры.
Так что же, не вдаваясь в подробности внутренней реализации, можно думать о Clickhouse как о быстрой SQL базе данных, только без транзакций (что-то вроде Timescale в PosgreSQL)?
Но всё-таки есть некоторые возможности Кликхауса (они, честно говоря, не на поверхности), которые заставляют задуматься о нем не как о табличной SQL бд).
Одна из таких особенностей - это Nested
структуры.
Этот тип данных представляет собой вложенную таблицу. В отличие от, например, хранения JSON данных в PosgreSQL эта таблица будет first-class структурой, т.е. поддерживать все операции, что и обычные таблицы. Также судя по всему эти данные также хранятся как точно так же, как и основные данные, в виде столбцов. Что ещё удивительнее, поддерживается больше одного уровня вложенности (как экспериментальная фича) хотя большой вопрос насколько это практично.
Одина эта единственная фича сильно отдаляет Кликхаус от традиционных SQL СУБД, и гораздо больше напоминает вышеупомянутые структуры key-value, где ключом будет значение в nested столбце, который ссылается на данные-таблицу.
Стоит также отметить, что судя по всему эта фича ещё довольно экспериментальная. Вставка в такие таблицы, с точки зрения документации достаточно загадочное действие: Предполагается, что вставлять в такие таблицы нужно из JSON-объектов, но вот беда - в моей текущей версии Кликхауса они не поддерживаются даже как экспериментальная функция.
После долгих страданий, всё же удалось найти решение - мы используем тип данных Map
, который чем-то схож с JSON,
однако поддерживает значения только одного типа. Обойти это ограничение можно, храня значения в String
и преобразовывая перед непосредственной
вставкой обратно в их родной тип (решение, вероятно, не очень по эффективности, зато рабочее).
WITH
_src_category_agg AS (
SELECT
groupArray(map(
'category_id' , toString(category_id),
'category_text', category_text
)) AS nested_data
FROM
...
SELECT
arrayMap(x -> toUInt64(x['category_id']), nested_data) AS category_ids,
arrayMap(x -> x['category_text'] , nested_data) AS category_texts,
...
FROM
_src_category_agg
Сейчас можно предположить, что несмотря на внешнюю кажимость SQL базой данных, Clickhouse вероятно будет развивать NoSQL особенности, представляя собой своего рода гибрид между типичными реляционными БД и разного рода альтернативными решениями хранения данных.