.
Для поста про ORDER BY была создана github репа, в ней есть пайплайн который каждый 5 минут получает погодные данные по API и складывает их в raw таблицу.
Глянуть схему 👀
.
MATERIALIZED VIEW (MV) - можно рассматривать как триггер, реагирующий на вставку данных (в отличие от триггеров в реляционках, реагирует на блок вставляемых данных, а не на отдельную строку ☝️). В Clickhouse MV отделено от целевой таблицы, поэтому для себя MV представляю как процесс, запускающийся для вставляемых данных и загружающий их в целевую таблицу.
.
При помощи MV можно решать ряд задач:
▪️парсинг сырых данных
▪️фильтрация сырья
▪️роутинг данных
▪️агрегация данных
.
На примере решим первую задачку - парсинг сырья. В нашем пайплайне исходные данные сохраняются в таблицу
cdc.openweathermap_raw:CREATE TABLE cdc.openweathermap_raw
(
record_timestamp DateTime64(6),
record_value String
)
ENGINE=MergeTree
ORDER BY (record_timestamp)
где
record_value - json объект с погодой, который получаем из api. Создадим MV, который будет парсить json и сохранять в таблицу cdc.openweathermap. Посмотреть пример json можно на сайте.Пишем DDL целевой таблицы:
CREATE OR REPLACE TABLE cdc.openweathermap
(
record_timestamp DateTime64,
dt DateTime,
main String,
description String,
temp Float64,
feels_like Float64,
pressure Float64,
humidity Float64
)
ENGINE=MergeTree
PARTITION BY toStartOfWeek(record_timestamp)
ORDER BY (main, description, record_timestamp)
Вытаскиваем поля: время (оно в UTC), общее описание погоды, детальное описание, температура, ощущаемая температура, давление (ГПаскаль), влажность.
Именно MV и будет парсить и перекладывать данные из сырья в
cdc.openweathermap. Напишем запрос, который парсит данные:SELECT record_timestamp ,
FROM_UNIXTIME(toUInt64(JSONExtractString(record_value, 'dt'))) AS dt,
JSONExtractString(arrayElement(JSONExtractArrayRaw(record_value, 'weather'), 1), 'main') AS main,
JSONExtractString(arrayElement(JSONExtractArrayRaw(record_value, 'weather'), 1), 'description') AS description,
JSONExtractFloat(JSONExtractString(record_value, 'main'), 'temp') AS temp ,
JSONExtractFloat(JSONExtractString(record_value, 'main'), 'feels_like') AS feels_like,
0.750062 * JSONExtractUInt(JSONExtractString(record_value, 'main'), 'pressure') AS pressure,
JSONExtractUInt(JSONExtractString(record_value, 'main'), 'humidity') AS humidity
FROM cdc.openweathermap_raw
Чтобы превратить тыкву в золушку необходимо добавить код создания MV: по классике что создаем, где создаем и для для MV куда пишем данные (этот кусочек ниже):
CREATE MATERIALIZED VIEW cdc.openweathermap_mv
TO cdc.openweathermap
...