docs(course): добавлен урок 3 (ODS→DDS, сборка сущностей и сироты)
- Зачем:
- собрать разрозненные кусочки ODS в цельные сущности DDS и ввести понятие
целостности связей (сироты), пока без жёсткого гейта — он в уроке 4
- Что:
- добавлен docs/course/lessons/03_ods_to_dds.md: сущности dds.click/dds.event,
UNION-универсум кликов, дедуп через argMax, LEFT JOIN, понятие сироты,
управляемая правка (вставка сироты), recap STG→ODS→DDS, заметка про DM
- §3.1: «поток данных» в шапку sql/dds/30_ods_to_dds.sql
- демоут DM: убран закомментированный пример материализации в
sql/dm/40_dds_to_dm.sql, добавлены «поток данных» и заметка «VIEW сейчас,
материализуем если затормозит» со ссылкой на docs/ARCHITECTURE.md
- sql/ddl/dm/40_dm.sql: пояснён seed 1919 в groupArraySample, поправлен
неверный комментарий «последние» (groupArraySample берёт случайную выборку)
- README курса: индекс обновлён до «уроки 0–3»
- Проверка:
- LIMIT=50 make transform: dds.click=26, dds.event=50, orphan_events=0
- §4 на стенде: вставка события-сироты → orphan 0→1; LEFT JOIN в
dm.v_events_enriched даёт NULL по полям клика; make transform откатывает к 0
- /ai-text-lint (article): house style сохранён, AI-маркеры не найдены
This commit is contained in:
@@ -139,7 +139,9 @@ SELECT
|
||||
arrayDistinct(groupArray(page_url_path)) AS pages_visited, -- Уникальные страницы
|
||||
arrayDistinct(groupArray(geo_country)) AS countries, -- Страны (если менялась)
|
||||
arrayDistinct(groupArray(device_type)) AS devices, -- Устройства (если менялось)
|
||||
-- Берём последние UTM-метки сессии (для атрибуции)
|
||||
-- Берём одну UTM-метку сессии (для атрибуции).
|
||||
-- groupArraySample(1, 1919) выбирает 1 случайный элемент; 1919 — фиксированный seed,
|
||||
-- чтобы выборка была воспроизводимой между прогонами (одинаковый seed → один результат).
|
||||
groupArraySample(1, 1919)(utm_source)[1] AS utm_source_last,
|
||||
groupArraySample(1, 1919)(utm_medium)[1] AS utm_medium_last
|
||||
FROM dm.v_events_enriched
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
-- ============================================================================
|
||||
-- Batch-трансформация: ODS → DDS
|
||||
-- ============================================================================
|
||||
-- Поток данных:
|
||||
-- ods.device_by_click + ods.geo_by_click → dds.click (контекст клика)
|
||||
-- ods.browser_event + ods.location_event → dds.event (контекст события)
|
||||
--
|
||||
-- Что делает:
|
||||
-- Собирает "чистые" сущности из типизированных данных ODS для аналитики.
|
||||
-- Использует argMax() для получения последней версии строк по ключу.
|
||||
|
||||
+8
-25
@@ -1,6 +1,10 @@
|
||||
-- ============================================================================
|
||||
-- Batch-трансформация: DDS → DM (Data Quality summary)
|
||||
-- ============================================================================
|
||||
-- Поток данных:
|
||||
-- dds.click + dds.event + ods.* + stg.* → dm.dq_summary (сводка по слоям)
|
||||
-- Сами витрины (dm.v_*) — это VIEW поверх DDS, создаются в sql/ddl/dm/40_dm.sql.
|
||||
--
|
||||
-- Что делает:
|
||||
-- Собирает статистику по всем слоям (stg/ods/dds) для мониторинга качества данных.
|
||||
-- Позволяет быстро проверить, сколько данных прошло через каждый слой
|
||||
@@ -9,33 +13,12 @@
|
||||
-- Важно:
|
||||
-- Таблица dq_summary пересоздаётся при каждом запуске (TRUNCATE + INSERT),
|
||||
-- чтобы не накапливать дубликаты при повторных прогонах.
|
||||
--
|
||||
-- Витрины DM сейчас — это VIEW (логика без копии данных). Если тяжёлая агрегация
|
||||
-- начнёт тормозить, её материализуют в таблицу; пример — в docs/ARCHITECTURE.md,
|
||||
-- раздел «Материализация витрин».
|
||||
-- ============================================================================
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Пример материализации тяжёлой витрины (закомментировано)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Если VIEW dm.v_daily_traffic работает медленно, можно создать таблицу:
|
||||
--
|
||||
-- CREATE TABLE IF NOT EXISTS dm.daily_traffic_mart
|
||||
-- (
|
||||
-- event_date Date,
|
||||
-- geo_country LowCardinality(Nullable(String)),
|
||||
-- device_type LowCardinality(Nullable(String)),
|
||||
-- browser_name LowCardinality(Nullable(String)),
|
||||
-- utm_source LowCardinality(Nullable(String)),
|
||||
-- utm_medium LowCardinality(Nullable(String)),
|
||||
-- events UInt64,
|
||||
-- uniq_clicks UInt64,
|
||||
-- uniq_users UInt64
|
||||
-- )
|
||||
-- ENGINE = ReplacingMergeTree(event_date)
|
||||
-- PARTITION BY toYYYYMM(event_date)
|
||||
-- ORDER BY (event_date, geo_country, device_type, browser_name, utm_source, utm_medium);
|
||||
--
|
||||
-- TRUNCATE TABLE dm.daily_traffic_mart;
|
||||
-- INSERT INTO dm.daily_traffic_mart SELECT * FROM dm.v_daily_traffic;
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Таблица для сводки по качеству данных (DQ summary)
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user