docs(dds): добавлены комментарии и исправлены ошибки в DWH

- Зачем:
  - закрыты задачи P0 и P1 из ревью архитектуры для повышения понятности стенда для студентов.
- Что:
  - исправлен distribution key для airport_traffic в дизайн-документе.
  - добавлены комментарии о генерации SK и отсутствии SK в фактах.
  - создан документ docs/dag_execution_order.md с описанием порядка запуска DAG-ов.
  - объяснена логика late-arriving dimensions и batch resolver.
  - добавлена legacy-пометка для хелпера greenplum.py.
- Проверка:
  - визуальная проверка добавленных комментариев и новых файлов.
This commit is contained in:
2026-03-01 17:50:53 +03:00
parent e29a249830
commit 768334453f
8 changed files with 65 additions and 10 deletions
+7 -7
View File
@@ -53,7 +53,7 @@ GP-специфичная best practice, которую забывают даж
### P0: Фактическая ошибка (исправить до показа студентам)
- [ ] **Противоречие в distribution key для airport_traffic**
- [x] **Противоречие в distribution key для airport_traffic**
- `bookings_dm_design.md` (строка 182): `DISTRIBUTED BY (traffic_date)`
- `sales_report_ddl.sql`: явно объясняет, почему distribution by date — антипаттерн
- **Нужно**: исправить на `DISTRIBUTED BY (airport_sk)` в дизайн-документе
@@ -61,27 +61,27 @@ GP-специфичная best practice, которую забывают даж
### P1: Высокий эффект, минимум усилий (комментарии и документация)
- [ ] **Нет объяснения «почему не SERIAL» в генерации SK**
- [x] **Нет объяснения «почему не SERIAL» в генерации SK**
- `MAX(sk) + ROW_NUMBER()` корректен для GP, но студент на PostgreSQL/Snowflake будет использовать `IDENTITY`/`SEQUENCE`
- **Нужно**: 4-строчный комментарий в `sql/dds/dim_airports_load.sql`
- [ ] **Факт без суррогатного ключа — не объяснено «почему»**
- [x] **Факт без суррогатного ключа — не объяснено «почему»**
- Натуральный (ticket_no, flight_id) как grain — правильное Kimball-моделирование
- **Нужно**: комментарий в `sql/dds/fact_flight_sales_ddl.sql`
- [ ] **Нет упоминания cross-DAG зависимостей**
- [x] **Нет упоминания cross-DAG зависимостей**
- STG, ODS, DDS, DM — отдельные DAG-и с `schedule=None`, студент может не понять порядок
- **Нужно**: комментарий в docstring каждого DAG или `docs/dag_execution_order.md`
- [ ] **Late-arriving dimensions не упомянуты**
- [x] **Late-arriving dimensions не упомянуты**
- Факт делает LEFT JOIN → `passenger_sk = NULL` при опоздании; нет механизма исправления
- **Нужно**: комментарий в `sql/dds/fact_flight_sales_load.sql` у LEFT JOIN-ов
- [ ] **Batch resolver недообъяснён**
- [x] **Batch resolver недообъяснён**
- `_resolve_stg_batch_id` с INTERSECT по 4 таблицам — нет комментария **зачем** нужна согласованность
- **Нужно**: комментарий в `airflow/dags/bookings_to_gp_ods.py` перед SQL-запросом
- [ ] **`helpers/greenplum.py` без пометки «legacy»**
- [x] **`helpers/greenplum.py` без пометки «legacy»**
- Использует прямой psycopg2 + ENV — противоречит PostgresOperator-подходу
- **Нужно**: docstring «LEGACY: только для CSV-пайплайна» в `airflow/dags/helpers/greenplum.py`
+1 -1
View File
@@ -178,7 +178,7 @@ FROM traffic GROUP BY ...
**Загрузка**: Инкрементальный UPSERT по HWM (`_load_ts`). Из дельты фактов определяем затронутые `(traffic_date, airport_sk)`, пересчитываем агрегаты только для них.
**Хранение**: `DISTRIBUTED BY (traffic_date)`, heap
**Хранение**: `DISTRIBUTED BY (airport_sk)`, heap
**Учит**: HWM-инкрементальность, TEMP TABLE для однократной агрегации, dual-role dimension join (UNION ALL), conditional aggregation (CASE WHEN + SUM), паттерн "unpivot → aggregate"