Шаги проектирования хранилища данных
Проектирование DWH по Kimball (Dimensional Modeling):
1. Определить бизнес-процесс
Что анализируем? Примеры:
- Продажи в магазинах
- Клики на сайте
- Звонки в колл-центре
2. Выбрать grain (зерно факта)
Grain — самый детальный уровень данных в fact-таблице.
Например:
- Одна строка = одна позиция заказа (
order_id + product_id) - Одна строка = один заказ (
order_id) - Одна строка = один день в одном магазине
Выбор grain определяет всё остальное.
3. Определить измерения
Что является контекстом для факта?
- Кто? → dim_customer
- Что? → dim_product
- Где? → dim_store
- Когда? → dim_date
4. Определить метрики факта
Числовые аддитивные показатели:
- revenue, cost, profit, quantity
Аддитивные: можно суммировать по любому измерению Полуаддитивные: можно суммировать не по всем (например, остаток на складе) Неаддитивные: нельзя суммировать (курс валюты, коэффициенты)
5. Определить медленно меняющиеся измерения
Что меняется со временем?
- Тир лояльности покупателя → SCD Type 2
- Адрес магазина → SCD Type 1 (если история не нужна)
- Цена товара → зависит от требований
6. ETL-процесс
Как и когда данные будут загружаться в DWH?
- Batch (ночная загрузка)
- Near real-time (каждые N минут)
- Streaming (каждую секунду)
Наш проект использует исторический batch: данные за Jan–Jun 2024.
Conformed dimensions — одно измерение на много фактов
Если бы в DWH появилась вторая факт-таблица (например, fact_returns
для возвратов), у нас есть выбор: сделать для неё отдельное dim_date
или переиспользовать существующее. Измерение, которое используется
несколькими факт-таблицами без изменений — это conformed dimension
(согласованное измерение).
Выгода: покупатель с customer_id = 9 в dim_customer — это один и тот
же покупатель что для fact_sales, что для fact_returns. Это
позволяет строить отчёты, которые объединяют несколько факт-таблиц
через общее измерение («выручка и возвраты по одному и тому же
покупателю»), не изобретая сопоставление ключей заново.
Три типа факт-таблиц
- Transaction fact — одна строка на одно событие.
fact_sales— ровно этот тип: строка появляется в момент продажи и больше не меняется. - Periodic snapshot — одна строка на сущность за период (например, остаток товара на складе на конец каждого дня), даже если за этот период ничего не происходило.
- Accumulating snapshot — одна строка на процесс целиком, которая обновляется по мере прохождения этапов (например, заказ: дата оформления → дата отгрузки → дата доставки в одной и той же строке).
Большинство учебных примеров DWH — transaction fact, но в реальных проектах часто нужны все три вида одновременно для разных вопросов бизнеса.
Частые ошибки
- Выбирают grain после того, как уже начали писать ETL — если зерно выбрано неверно, приходится переделывать и схему, и загрузку. Grain — первое решение, не последнее.
- Делают отдельное измерение под каждую факт-таблицу — там, где сущность одна и та же (например, покупатель), это должно быть одно conformed dimension, а не дублирующиеся копии.
- Путают periodic snapshot с transaction fact — если бизнесу нужен ответ на вопрос «сколько было на складе на конец каждого дня», а не «когда произошла операция», transaction fact для этого не годится в принципе — нужен snapshot с одной строкой на день, даже без движений.
Запомни
Методология Kimball — bottom-up от конкретного бизнес-процесса, не попытка сразу построить универсальную схему на всё. Grain — первое и самое важное решение. Conformed dimension — одно измерение, общее для нескольких факт-таблиц. Три типа фактов — transaction (событие), periodic snapshot (срез на момент), accumulating snapshot (прогресс процесса, строка обновляется).
Микро-практика
- Нужен отчёт «остаток на складе на конец каждого дня, даже если движений не было» → periodic snapshot fact.
- Заказ проходит статусы
оформлен → оплачен → отгружен → доставлен, и нужно видеть время между этапами в одной строке → accumulating snapshot fact. - Строится вторая факт-таблица для возвратов, а покупатели — те же, что
и в продажах → переиспользовать существующее
dim_customerкак conformed dimension, не создавать новое.
Прочитайте урок до конца — прогресс засчитается автоматически