Каскадные материализованные представления
Этот пример демонстрирует, как создать материализованное представление, а затем как создать второе материализованное представление на основе первого. На этой странице вы увидите, как это сделать, множество возможностей и ограничения. Разные варианты использования могут быть решены с помощью создания материализованного представления, используя второе материализованное представление в качестве источника.
Пример:
Мы будем использовать фейковый набор данных с количеством просмотров в час для группы доменных имен.
Наша цель
- Нам нужны данные, агрегированные по месяцам для каждого доменного имени,
- Нам также нужны данные, агрегированные по годам для каждого доменного имени.
Вы можете выбрать один из следующих вариантов:
- Написать запросы, которые будут считывать и агрегировать данные во время запроса SELECT
- Подготовить данные на этапе загрузки в новый формат
- Подготовить данные на этапе загрузки к конкретной агрегации.
Подготовка данных с использованием материализованных представлений позволит вам ограничить количество данных и расчетов, которые необходимо выполнить ClickHouse, что сделает ваши запросы SELECT быстрее.
Исходная таблица для материализованных представлений
Создайте исходную таблицу. Поскольку наши цели заключаются в отчетности по агрегированным данным, а не по отдельным строкам, мы можем обработать данные, передав информацию в материализованные представления и отбрасывая фактические входящие данные. Это соответствует нашим целям и экономит место для хранения, поэтому мы используем движок таблиц Null
.
Вы можете создать материализованное представление на основе таблицы Null. Таким образом, данные, записанные в таблицу, будут оказывать влияние на представление, но исходные сырые данные все равно будут отброшены.
Таблица и материализованное представление с месячной агрегацией
Для первого материализованного представления необходимо создать таблицу Target
, в этом примере это будет analytics.monthly_aggregated_data
, и мы будем хранить сумму просмотров по месяцам и доменным именам.
Материализованное представление, которое будет передавать данные в целевую таблицу, будет выглядеть следующим образом:
Таблица и материализованное представление с годовой агрегацией
Теперь мы создадим второе материализованное представление, которое будет связано с нашей предыдущей целевой таблицей monthly_aggregated_data
.
Сначала мы создадим новую целевую таблицу, которая будет хранить сумму просмотров, агрегированных по годам для каждого доменного имени.
Этот шаг определяет каскад. Оператор FROM
будет использовать таблицу monthly_aggregated_data
, это означает, что поток данных будет таким:
- Данные поступают в таблицу
hourly_data
. - ClickHouse передаст полученные данные в первое материализованное представление
monthly_aggregated_data
, - Наконец, данные, полученные на шаге 2, будут переданы в
year_aggregated_data
.
Распространенное недопонимание при работе с материализованными представлениями заключается в том, что данные считываются из таблицы. Это не то, как работают Материализованные представления
; передаваемые данные - это вставленный блок, а не конечный результат вашей таблицы.
Представьте себе в этом примере, что использованный движок в monthly_aggregated_data
- это CollapsingMergeTree; данные, переданные в наше второе материализованное представление year_aggregated_data_mv
, не будут окончательным результатом сжатой таблицы, а передадут блок данных с полями, определенными в SELECT ... GROUP BY
.
Если вы используете CollapsingMergeTree, ReplacingMergeTree или даже SummingMergeTree и планируете создать каскадное материализованное представление, вам нужно понять ограничения, описанные здесь.
Пример данных
Теперь время протестировать наше каскадное материализованное представление, вставив некоторые данные:
Если вы выполните SELECT содержимого analytics.hourly_data
, вы увидите следующее, поскольку движок таблицы - это Null
, но данные были обработаны.
Мы использовали небольшой набор данных, чтобы быть уверенными, что можем следить и сравнивать результат с тем, что ожидаем, как только ваш поток будет корректным с небольшим набором данных, вы можете перейти к большому объему данных.
Результаты
Если вы попытаетесь запросить целевую таблицу, выбрав поле sumCountViews
, вы увидите двоичное представление (в некоторых терминалах), так как значение не хранится как число, а как тип AggregateFunction.
Чтобы получить окончательный результат агрегации, вы должны использовать суффикс -Merge
.
Вы можете увидеть специальные символы, хранящиеся в AggregateFunction, с помощью этого запроса:
Напротив, давайте попробуем использовать суффикс Merge
, чтобы получить значение sumCountViews
:
В AggregatingMergeTree
мы определили AggregateFunction
как sum
, так что мы можем использовать sumMerge
. Когда мы используем функцию avg
на AggregateFunction
, мы будем использовать avgMerge
и так далее.
Теперь мы можем убедиться, что материализованные представления соответствуют целям, которые мы определили.
Теперь, когда данные хранятся в целевой таблице monthly_aggregated_data
, мы можем получить данные, агрегированные по месяцам для каждого доменного имени:
Данные, агрегированные по годам для каждого доменного имени:
Объединение нескольких исходных таблиц в одну целевую таблицу
Материализованные представления также могут быть использованы для объединения нескольких исходных таблиц в одну целевую таблицу. Это полезно для создания материализованного представления, которое будет похоже на логику UNION ALL
.
Сначала создайте две исходные таблицы, представляющие разные наборы метрик:
Затем создайте таблицу Target
с объединенным набором метрик:
Создайте два материализованных представления, указывающих на одну и ту же таблицу Target
. Вам не нужно явно включать отсутствующие колонки:
Теперь, когда вы вставляете значения, эти значения будут агрегироваться в соответствующие колонки в таблице Target
:
Объединенные показы и клики вместе в таблице Target
:
Этот запрос должен выводить что-то вроде: