Перейти к основному содержимому
Перейти к основному содержимому

Каскадные материализованные представления

Этот пример демонстрирует, как создать материализованное представление, а затем как каскадировать второе материализованное представление к первому. На этой странице вы увидите, как это сделать, многие возможности и ограничения. Разные случаи использования могут быть решены, создавая материализованное представление, используя второе материализованное представление в качестве источника.


Пример:

Мы будем использовать фейковый набор данных с количеством просмотров в час для группы доменных имен.

Наша цель

  1. Нам нужны данные, агрегированные по месяцам для каждого доменного имени,
  2. Нам также нужны данные, агрегированные по годам для каждого доменного имени.

Вы можете выбрать один из этих вариантов:

  • Написать запросы, которые будут считывать и агрегировать данные во время запроса SELECT
  • Подготовить данные на этапе приема в новый формат
  • Подготовить данные во время приема к определенной агрегации.

Подготовка данных с помощью материализованных представлений позволит вам ограничить объем данных и расчетов, которые необходимо выполнить ClickHouse, ускоряя ваши SELECT запросы.

Исходная таблица для материализованных представлений

Создайте исходную таблицу, поскольку наши цели связаны с отчетностью по агрегированным данным, а не по отдельным строкам, мы можем разобрать их, передать информацию в материализованные представления и удалить входящие данные. Это соответствует нашим целям и экономит место, поэтому мы будем использовать движок таблицы Null.

примечание

Вы можете создать материализованное представление на таблице Null. Таким образом, данные, записанные в таблицу, повлияют на представление, но исходные необработанные данные все равно будут отброшены.

Ежемесячная агрегированная таблица и материализованное представление

Для первого материализованного представления нам нужно создать таблицу Target, для этого примера она будет analytics.monthly_aggregated_data, и мы будем хранить сумму просмотров по месяцам и доменным именам.

Материализованное представление, которое будет передавать данные в целевую таблицу, будет выглядеть следующим образом:

Ежегодная агрегированная таблица и материализованное представление

Теперь мы создадим второе материализованное представление, которое будет связано с нашей предыдущей целевой таблицей monthly_aggregated_data.

Сначала мы создадим новую целевую таблицу, которая будет хранить сумму просмотров, агрегированную по годам для каждого доменного имени.

Этот шаг определяет каскад. Оператор FROM будет использовать таблицу monthly_aggregated_data, это означает, что поток данных будет следующим:

  1. Данные поступают в таблицу hourly_data.
  2. ClickHouse передаст полученные данные в первое материализованное представление monthly_aggregated_data,
  3. Наконец, данные, полученные на шаге 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.

Сначала создайте две исходные таблицы, представляющие разные наборы метрик:

Затем создайте целевую таблицу с объединенным набором метрик:

Создайте два материализованных представления, указывающих на одну и ту же целевую таблицу. Вам не нужно явно включать отсутствующие столбцы:

Теперь, когда вы вставляете значения, эти значения будут агрегироваться по соответствующим столбцам в целевой таблице:

Объединенные показы и клики вместе в целевой таблице:

Этот запрос должен вернуть что-то вроде: