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