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:
+4
-13
@@ -9,21 +9,9 @@
|
||||
--
|
||||
-- Важно:
|
||||
-- - Наполнение ODS выполняется batch-процессом из sql/ods/20_stg_to_ods.sql
|
||||
-- - Materialized View STG → ODS в target-state не используются
|
||||
-- (а не Materialized View, как в STG): батч ради наблюдаемости пересчёта
|
||||
-- ============================================================================
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Удаляем legacy MV STG → ODS (если ранее были созданы)
|
||||
-- ----------------------------------------------------------------------------
|
||||
DROP TABLE IF EXISTS stg.mv_browser_raw_to_ods;
|
||||
DROP TABLE IF EXISTS stg.mv_browser_raw_to_ods_errors;
|
||||
DROP TABLE IF EXISTS stg.mv_location_raw_to_ods;
|
||||
DROP TABLE IF EXISTS stg.mv_location_raw_to_ods_errors;
|
||||
DROP TABLE IF EXISTS stg.mv_device_raw_to_ods;
|
||||
DROP TABLE IF EXISTS stg.mv_device_raw_to_ods_errors;
|
||||
DROP TABLE IF EXISTS stg.mv_geo_raw_to_ods;
|
||||
DROP TABLE IF EXISTS stg.mv_geo_raw_to_ods_errors;
|
||||
|
||||
-- ============================================================================
|
||||
-- BROWSER EVENTS
|
||||
-- ============================================================================
|
||||
@@ -46,6 +34,8 @@ CREATE TABLE IF NOT EXISTS ods.browser_event
|
||||
parse_errors Array(LowCardinality(String)) -- Ошибки парсинга (если есть)
|
||||
)
|
||||
ENGINE = ReplacingMergeTree(src_ingest_ts)
|
||||
-- Партиционируем по бизнес-дате события: у browser_event есть собственное время (event_ts).
|
||||
-- У click-контекста ниже (location/device/geo) такого времени нет — там партиция по дате загрузки.
|
||||
PARTITION BY toYYYYMM(event_date)
|
||||
ORDER BY (event_id)
|
||||
SETTINGS allow_nullable_key = 1;
|
||||
@@ -87,6 +77,7 @@ CREATE TABLE IF NOT EXISTS ods.location_event
|
||||
parse_errors Array(LowCardinality(String))
|
||||
)
|
||||
ENGINE = ReplacingMergeTree(src_ingest_ts)
|
||||
-- По дате загрузки: у location нет собственного времени события (только время приёма в STG)
|
||||
PARTITION BY toYYYYMM(toDate(src_ingest_ts))
|
||||
ORDER BY (event_id)
|
||||
SETTINGS allow_nullable_key = 1;
|
||||
|
||||
Reference in New Issue
Block a user