план витрин до stg слоя
This commit is contained in:
@@ -0,0 +1,222 @@
|
|||||||
|
# Схема БД DWH (Bookings → Greenplum)
|
||||||
|
|
||||||
|
> **Статус:** Проект в разработке. Реализован только STG слой (частично: bookings, tickets).
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Эта документация описывает архитектуру хранилища данных (DWH) для учебного проекта Airflow + Greenplum. Источник данных — демо-БД `bookings` (Postgres).
|
||||||
|
|
||||||
|
### Статус реализации по слоям
|
||||||
|
|
||||||
|
| Слой | Статус | Реализовано |
|
||||||
|
|------|--------|-------------|
|
||||||
|
| **Source** | ✅ Готово | Демо-БД bookings (Postgres) |
|
||||||
|
| **STG** | ⚠️ В процессе | 2 из 8 таблиц (bookings, tickets) |
|
||||||
|
| **DQ** | ⚠️ В процессе | Есть скрипты для bookings и tickets |
|
||||||
|
| **ODS** | ❌ Не реализован | Планируется |
|
||||||
|
| **DDS** | ❌ Не реализован | Планируется |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Полная схема потоков данных (Data Lineage)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
%% Стили
|
||||||
|
classDef source fill:#e1f5fe,stroke:#01579b,stroke-width:2px;
|
||||||
|
classDef stg fill:#fff9c4,stroke:#fbc02d,stroke-width:2px;
|
||||||
|
classDef dq fill:#ffe0b2,stroke:#ef6c00,stroke-width:2px;
|
||||||
|
classDef ods fill:#e0f2f1,stroke:#00695c,stroke-width:2px;
|
||||||
|
classDef dim fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px;
|
||||||
|
classDef fact fill:#ffccbc,stroke:#bf360c,stroke-width:4px;
|
||||||
|
|
||||||
|
%% 1. Source
|
||||||
|
subgraph Source_Postgres [Source: Postgres Bookings]
|
||||||
|
direction TB
|
||||||
|
SRC_Airports[airports_data]:::source
|
||||||
|
SRC_Airplanes[airplanes_data]:::source
|
||||||
|
SRC_Seats[seats]:::source
|
||||||
|
SRC_Bookings[bookings]:::source
|
||||||
|
SRC_Tickets[tickets]:::source
|
||||||
|
SRC_Flights[flights]:::source
|
||||||
|
SRC_Segments[segments]:::source
|
||||||
|
SRC_Boarding[boarding_passes]:::source
|
||||||
|
end
|
||||||
|
|
||||||
|
%% 2. STAGING (Load 1-to-1, AO-Row)
|
||||||
|
subgraph STG_Layer [Layer: STG Staging]
|
||||||
|
direction TB
|
||||||
|
STG_Airports[stg.airports]:::stg
|
||||||
|
STG_Airplanes[stg.airplanes]:::stg
|
||||||
|
STG_Seats[stg.seats]:::stg
|
||||||
|
STG_Bookings[stg.bookings]:::stg
|
||||||
|
STG_Tickets[stg.tickets]:::stg
|
||||||
|
STG_Flights[stg.flights]:::stg
|
||||||
|
STG_Segments[stg.segments]:::stg
|
||||||
|
STG_Boarding[stg.boarding_passes]:::stg
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Links Source to STG
|
||||||
|
SRC_Airports --> STG_Airports
|
||||||
|
SRC_Airplanes --> STG_Airplanes
|
||||||
|
SRC_Seats --> STG_Seats
|
||||||
|
SRC_Bookings --> STG_Bookings
|
||||||
|
SRC_Tickets --> STG_Tickets
|
||||||
|
SRC_Flights --> STG_Flights
|
||||||
|
SRC_Segments --> STG_Segments
|
||||||
|
SRC_Boarding --> STG_Boarding
|
||||||
|
|
||||||
|
%% 3. DATA QUALITY (Quality Checks)
|
||||||
|
subgraph DQ_Layer [Layer: DQ Data Quality]
|
||||||
|
direction TB
|
||||||
|
DQ_Bookings[dq.bookings_checks]:::dq
|
||||||
|
DQ_Tickets[dq.tickets_checks]:::dq
|
||||||
|
DQ_Flights[dq.flights_checks]:::dq
|
||||||
|
DQ_Segments[dq.segments_checks]:::dq
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Links STG to DQ
|
||||||
|
STG_Bookings --> DQ_Bookings
|
||||||
|
STG_Tickets --> DQ_Tickets
|
||||||
|
STG_Flights --> DQ_Flights
|
||||||
|
STG_Segments --> DQ_Segments
|
||||||
|
|
||||||
|
%% 4. ODS (3NF, Clean, Type, Heap)
|
||||||
|
subgraph ODS_Layer [Layer: ODS Operational Core]
|
||||||
|
direction TB
|
||||||
|
ODS_Airports[ods.airports]:::ods
|
||||||
|
ODS_Airplanes[ods.airplanes]:::ods
|
||||||
|
ODS_Seats[ods.seats]:::ods
|
||||||
|
ODS_Bookings[ods.bookings]:::ods
|
||||||
|
ODS_Tickets[ods.tickets]:::ods
|
||||||
|
ODS_Flights[ods.flights]:::ods
|
||||||
|
ODS_Segments[ods.segments]:::ods
|
||||||
|
ODS_Boarding[ods.boarding_passes]:::ods
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Links DQ to ODS
|
||||||
|
DQ_Bookings --> ODS_Bookings
|
||||||
|
DQ_Tickets --> ODS_Tickets
|
||||||
|
DQ_Flights --> ODS_Flights
|
||||||
|
DQ_Segments --> ODS_Segments
|
||||||
|
STG_Airports --> ODS_Airports
|
||||||
|
STG_Airplanes --> ODS_Airplanes
|
||||||
|
STG_Seats --> ODS_Seats
|
||||||
|
STG_Boarding --> ODS_Boarding
|
||||||
|
|
||||||
|
%% 5. DDS (Star Schema)
|
||||||
|
subgraph DDS_Layer [Layer: DDS Star Schema]
|
||||||
|
direction TB
|
||||||
|
|
||||||
|
%% Dimensions
|
||||||
|
DIM_Calendar[dim.calendar]:::dim
|
||||||
|
DIM_Airports[dim.airports]:::dim
|
||||||
|
DIM_Airplanes[dim.airplanes]:::dim
|
||||||
|
DIM_Tariffs[dim.tariffs]:::dim
|
||||||
|
DIM_Passengers[dim.passengers]:::dim
|
||||||
|
|
||||||
|
%% Fact
|
||||||
|
FACT_Sales[fact.flight_sales]:::fact
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Transformations ODS to DDS
|
||||||
|
|
||||||
|
%% Form reference tables
|
||||||
|
ODS_Airports --> DIM_Airports
|
||||||
|
|
||||||
|
ODS_Airplanes --> DIM_Airplanes
|
||||||
|
ODS_Seats -.->|Enrich total_seats| DIM_Airplanes
|
||||||
|
|
||||||
|
ODS_Segments -.->|Extract distinct| DIM_Tariffs
|
||||||
|
|
||||||
|
ODS_Tickets -->|Extract Unique| DIM_Passengers
|
||||||
|
|
||||||
|
%% Fact assembly (Main process)
|
||||||
|
ODS_Segments -->|Main Stream| FACT_Sales
|
||||||
|
ODS_Tickets -->|Join book_ref passenger_id| FACT_Sales
|
||||||
|
ODS_Flights -->|Join Times Status| FACT_Sales
|
||||||
|
ODS_Boarding -->|LEFT JOIN Seat No| FACT_Sales
|
||||||
|
|
||||||
|
%% Link dimensions to fact
|
||||||
|
DIM_Calendar -->|calendar_sk| FACT_Sales
|
||||||
|
DIM_Airports -->|departure_airport_sk| FACT_Sales
|
||||||
|
DIM_Airports -->|arrival_airport_sk| FACT_Sales
|
||||||
|
DIM_Airplanes -->|airplane_sk| FACT_Sales
|
||||||
|
DIM_Tariffs -->|tariff_sk| FACT_Sales
|
||||||
|
DIM_Passengers -->|passenger_sk| FACT_Sales
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Пояснения к схеме (для студентов)
|
||||||
|
|
||||||
|
Эта диаграмма покрывает 100% таблиц источника и показывает логику их трансформации. Вот на что стоит обратить внимание при обучении:
|
||||||
|
|
||||||
|
### 1. Ветка справочников (Reference Data)
|
||||||
|
|
||||||
|
* **`seats` + `airplanes` → `dim.airplanes`**: Здесь мы показываем пример **обогащения**. Таблица `seats` сама по себе в аналитике редко нужна отдельной сущностью. Мы используем её в ODS, чтобы посчитать общее количество мест (`total_seats`) и добавить это как атрибут в измерение самолётов (`dim.airplanes`).
|
||||||
|
|
||||||
|
* **`airports` → `dim.airports`**: Простой перенос (1-в-1), но в DDS мы можем добавить, например, поле `city_ru` и `city_en` как отдельные колонки, убрав JSON, который есть в источнике.
|
||||||
|
|
||||||
|
### 2. Ветка генерации измерений (Dimension Generation)
|
||||||
|
|
||||||
|
* **`tickets` → `dim.passengers`**: Это самая сложная трансформация для измерения. В источнике нет таблицы "Пассажиры". Мы должны объяснить студентам, что мы "майним" пассажиров из билетов. Важно: один и тот же пассажир может иметь разные записи с разными именами (опечатки, изменение фамилии), поэтому нужна логика SCD Type 2 для отслеживания изменений.
|
||||||
|
|
||||||
|
* **`segments` → `dim.tariffs`**: Таблицы тарифов физически нет в источнике, она "зашита" строкой (Economy, Business) в таблице полётов. Мы выносим её в отдельный справочник (Нормализация), чтобы в факте хранить маленький `INT` ключ, а не длинную строку.
|
||||||
|
|
||||||
|
### 3. Сборка Факта (`fact.flight_sales`)
|
||||||
|
|
||||||
|
Это центр звезды. Мы собираем его из четырёх ODS таблиц:
|
||||||
|
|
||||||
|
1. **`ods.segments`**: Основа (зерно факта — один полётный сегмент билета). Дает сумму (`amount`).
|
||||||
|
2. **`ods.tickets`**: Приджойниваем, чтобы получить `book_ref` и `passenger_id`.
|
||||||
|
3. **`ods.flights`**: Приджойниваем, чтобы получить точное время вылета/прилета (для FK на календарь) и статусы.
|
||||||
|
4. **`ods.boarding_passes`**: Приджойниваем (LEFT JOIN), чтобы узнать, **сел ли пассажир реально в самолёт** и на какое место (`seat_no`). Это важный бизнес-аспект: билет куплен, но посадочный не выдан = пассажир не летел.
|
||||||
|
|
||||||
|
### 4. Почему нет `dim.bookings`?
|
||||||
|
|
||||||
|
В классической Star Schema измерения — это справочники (airports, aircrafts, passengers), а факты — транзакции/события (sales, bookings).
|
||||||
|
|
||||||
|
`bookings` — это транзакционная таблица, а не справочник. Вместо отдельного измерения `dim.bookings` мы храним:
|
||||||
|
- `book_ref` — бизнес-ключ бронирования (в факте)
|
||||||
|
- `book_date` — дата бронирования (в факте)
|
||||||
|
|
||||||
|
Это позволяет отвечать на вопросы типа: *"За сколько дней до вылета люди обычно покупают билеты?"* (разница между `book_date` и датой вылета из `dim.calendar`).
|
||||||
|
|
||||||
|
### 5. Суррогатные ключи (Surrogate Keys)
|
||||||
|
|
||||||
|
В Star Schema факт должен ссылаться на суррогатные ключи (SK) измерений, а не на бизнес-ключи:
|
||||||
|
|
||||||
|
| Бизнес-ключ | Суррогатный ключ | Преимущество |
|
||||||
|
|-------------|------------------|--------------|
|
||||||
|
| `airport_code CHAR(3)` | `airport_sk INT` | Меньший размер, стабильность |
|
||||||
|
| `airplane_code TEXT` | `airplane_sk INT` | Меньший размер, стабильность |
|
||||||
|
| `passenger_id TEXT` | `passenger_sk INT` | Меньший размер, отслеживание изменений |
|
||||||
|
|
||||||
|
### 6. Слой DQ (Data Quality)
|
||||||
|
|
||||||
|
Между STG и ODS добавлен слой Data Quality для проверки качества данных. В проекте уже есть скрипты:
|
||||||
|
- `sql/stg/bookings_dq.sql`
|
||||||
|
- `sql/stg/tickets_dq.sql`
|
||||||
|
|
||||||
|
На схеме показаны примеры проверок для всех таблиц, которые должны быть реализованы.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## История изменений
|
||||||
|
|
||||||
|
| Дата | Версия | Описание изменений |
|
||||||
|
|------|--------|-------------------|
|
||||||
|
| 2025-01-17 | 1.1 | Исправлены названия таблиц (`aircrafts_data` → `airplanes_data`, `ticket_flights` → `segments`), удалено `dim.bookings`, добавлены суррогатные ключи, добавлен слой DQ, исправлены связи |
|
||||||
|
| 2025-01-XX | 1.0 | Первоначальная версия |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- [ ] Реализовать STG слой полностью (все 8 таблиц)
|
||||||
|
- [ ] Реализовать DQ слой для всех таблиц
|
||||||
|
- [ ] Реализовать ODS слой
|
||||||
|
- [ ] Реализовать DDS слой (измерения и факт)
|
||||||
|
- [ ] Создать DAG для загрузки ODS
|
||||||
|
- [ ] Создать DAG для загрузки DDS
|
||||||
Reference in New Issue
Block a user