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

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

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


Пример:

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

Наша Цель

  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.

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

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

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

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

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

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