docs(course): добавлен урок 2 (STG→ODS, типизация и DQ-split)

- Зачем:
  - нужен учебный урок «руки» про типизацию слоя ODS и разделение
    чистых/битых записей; по пути убрать мусор и неочевидности в
    эталонном пути, чтобы он читался за один проход.
- Что:
  - добавлен lessons/02_stg_to_ods.md по LESSON_STANDARD (6 секций,
    режим «руки», эталон голоса — урок 1); регистр смягчён под уровень
    «обзорно» с расшифровкой терминов (click-контекст, WITH, двойной учёт).
  - 20_stg_to_ods.sql: поток данных в шапку + блок «DQ-split» (почему
    строка может попасть и в основную таблицу, и в *_errors).
  - 20_ods.sql: убран мусорный блок из 8 DROP TABLE mv_*_to_ods;
    пояснено разное партиционирование (browser — по бизнес-дате,
    click-контекст — по дате загрузки).
- Проверка:
  - make ddl && make transform — проходят чисто, counts не изменились
    (browser/location 50, device/geo 26 дедуп, *_errors 0).
  - правка §4 (toFloat64OrNull→toInt64OrNull для geo_latitude) на стенде
    даёт geo_by_click_errors 0→50 и NULL-широту с флагом bad_geo_latitude.
This commit is contained in:
2026-06-05 17:08:29 +03:00
parent b15ee90939
commit 256ac14c66
3 changed files with 375 additions and 13 deletions
+9
View File
@@ -1,11 +1,20 @@
-- ============================================================================
-- Batch-трансформация: STG → ODS
-- ============================================================================
-- Поток данных:
-- stg.*_raw → ods.* (валидный ключ) + ods.*_errors (любая ошибка)
--
-- Назначение:
-- - Перенос типизации STG → ODS из Materialized View в управляемый batch
-- - Полная пересборка ODS для прозрачного мониторинга в Airflow
-- - Сохранение DQ-логики: parse_errors + отдельные *_errors таблицы
--
-- DQ-split (почему одна строка может попасть в оба места):
-- - Основная таблица ods.* — строки с валидным КЛЮЧОМ (event_id / click_id).
-- В ней допустимы parse_errors по НЕключевым полям — строка остаётся, но помечена.
-- - Таблица ods.*_errors — копия строк с ЛЮБОЙ ошибкой парсинга (для разбора).
-- Поэтому строка с валидным ключом, но битым неключевым полем, попадёт И туда, И туда.
--
-- Когда запускать:
-- - В DAG etl_pipeline перед ODS → DDS
-- - После загрузки очередного среза данных в Kafka/STG