Каскадные материализованные представления
Этот пример демонстрирует, как создать материализованное представление, а затем как каскадировать второе материализованное представление к первому. На этой странице вы увидите, как это сделать, многие возможности и ограничения. Разные случаи использования могут быть решены, создавая материализованное представление, используя второе материализованное представление в качестве источника.
Пример:
Мы будем использовать фейковый набор данных с количеством просмотров в час для группы доменных имен.
Наша цель
- Нам нужны данные, агрегированные по месяцам для каждого доменного имени,
- Нам также нужны данные, агрегированные по годам для каждого доменного имени.
Вы можете выбрать один из этих вариантов:
- Написать запросы, которые будут считывать и агрегировать данные во время запроса 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
.
Сначала создайте две исходные таблицы, представляющие разные наборы метрик:
Затем создайте целевую таблицу с объединенным набором метрик:
Создайте два материализованных представления, указывающих на одну и ту же целевую таблицу. Вам не нужно явно включать отсутствующие столбцы:
Теперь, когда вы вставляете значения, эти значения будут агрегироваться по соответствующим столбцам в целевой таблице:
Объединенные показы и клики вместе в целевой таблице:
Этот запрос должен вернуть что-то вроде: