diff --git a/dwh-modeling/README.md b/dwh-modeling/README.md index d29d747..6bafb58 100644 --- a/dwh-modeling/README.md +++ b/dwh-modeling/README.md @@ -294,38 +294,58 @@ AND (dim_customer.valid_to IS NULL OR fact_sales.order_date < dim_customer.valid ### 1. 3NF (третья нормальная форма) *Источник: Билл Инмон (Bill Inmon)* -✅ **Плюсы**: -- Минимум избыточности при строгих ключах и правилах дедупликации. -- Проще поддерживать единую терминологию и НСИ (reference data). -- Атрибуты и справочники легко расширять. +Если упростить, 3NF - это когда данные о разных бизнес-сущностях хранятся в отдельных таблицах и связываются ключами: клиент, заказ, город, регион, страна и т.д. Вместо одной большой таблицы с большим числом дублирующихся данных мы получаем цепочку таблиц, связанных ключами: `Заказ → Клиент → Город → Регион → Страна`. JOIN-ов становится больше, зато одно и то же свойство (например, название города) хранится в одном месте, а не дублируется в каждой строке заказа. -❌ **Минусы**: -- Много JOIN даже для простых отчётов. -- Историчность (SCD2) усложняет таблицы. -- Новые источники дороже гармонизировать (привести к канону). +Исторически подход с ядром в 3NF чаще связывают с Биллом Инмоном (Bill Inmon): сначала проектируют корпоративную модель данных ядра в 3NF (сущности, атрибуты, связи), а уже поверх неё строят витрины. -📌 **Когда выбирать**: -→ Корпоративные DWH, где важна *единая терминология* и *долгосрочная поддержка*. -→ Стабильные домены (финансы, НСИ, договоры) и умеренная динамика изменений. +![Пример цепочки в 3NF](images/3NF-small.jpg) + +* Данные о сущностях разнесены по отдельным таблицам: клиент, заказ, продукт. +* Минимум дублирования: общие атрибуты хранятся в одном месте, таблицы связаны ключами. + +**Плюсы:** + +* Удобно поддерживать **единую «карту бизнеса»**: где живут «клиент», «заказ», «договор» и как они связаны; +* Меньше дублирования: одно и то же свойство хранится в одном месте, проще исправлять ошибки и контролировать качество; +* Проще собирать разные витрины поверх ядра: внизу держим детальные данные и связи, наверху показываем «как удобно». + +**Минусы:** + +* Если строить отчёты прямо по ядру, запросы часто получаются тяжёлыми: много `JOIN`-ов и условий; +* История (SCD Type 2) увеличивает объём данных и добавляет временной контекст в соединения - запросы становятся сложнее и менее удобными для чтения; +* Изменения в бизнес-процессах приходится аккуратно встраивать в существующую модель: чем старше ядро, тем дороже большие переделки. + +Частый паттерн: **ядро в 3NF** (подход ближе к Инмону), витрины - в Звезде. --- ### 2. Звезда (Star Schema) *Источник: Ральф Кимболл (Ralph Kimball)* -✅ **Плюсы**: -- **Простота**: факт + несколько «плоских» измерений; -- **Скорость**: BI-системы любят звезду — запросы пишутся за 5 минут; -- **Понятно бизнесу**: «продажи по товарам и клиентам» — это ровно то, что в таблицах. +Самый распространённый способ построения таблиц для слоя витрин. -❌ **Минусы**: -- Дублирование: город будет повторяться в каждой строке клиента; -- Изменение структуры измерения — дорого (перестроить всю витрину). +Структура: + +* в центре - таблица фактов (события и метрики); +* вокруг - измерения, обычно денормализованные («плоские») - широкие таблицы со всеми атрибутами сущности. Мы сознательно избегаем цепочек справочников ради простоты запросов. + +Пример: `fact_sales` + `dim_date`, `dim_customer`, `dim_product`. + +![Звёздная схема вокруг fact_sales](images/star-model-small.jpg) + +Методология Ральфа Кимбалла (Ralph Kimball) как раз делает упор на такие звёздные схемы: витрины, которые максимально просты для чтения и понятны аналитикам и BI-инструментам. + +**Плюсы:** + +* проста для понимания: аналитикам и BI-инструментам удобно работать с такой моделью; +* меньше `JOIN`-ов - запросы обычно проще и быстрее; +* хорошо подходит для витрин под конкретные задачи. + +**Минусы:** + +* измерения денормализованы, поэтому атрибуты дублируются (например, регион повторяется у всех клиентов региона); +* изменения атрибутов могут требовать обновлять много строк в измерении. -📌 **Когда выбирать**: -→ Витрины (DM), а не ядро (DDS); -→ Начинающим командам и MVP; -→ Когда отчёты — главная цель. --- @@ -346,6 +366,8 @@ AND (dim_customer.valid_to IS NULL OR fact_sales.order_date < dim_customer.valid - **Satellite (Сателлит)** — *«какие у них свойства и как они менялись»*. Имя клиента, email, статус заказа, цены — всё с историей изменений. +![Пример модели Data Vault](images/data-vault-small.jpg) + 💡 **Главная мысль:** идентичность, связи и атрибуты живут **в разных таблицах**, поэтому: - историю проще хранить; @@ -435,23 +457,17 @@ AND (dim_customer.valid_to IS NULL OR fact_sales.order_date < dim_customer.valid *Источник: Ларс Рёне (Lars Rönnbäck)* -Ещё более атомарный подход: -- **Anchor** — сущность (клиент, товар); -- **Attribute** — атрибут (email, имя); -- **Tie** — связь (как Link в DV); -- Все таблицы — 2–3 столбца. +Anchor Modeling - ещё более атомарный подход к моделированию ядра, чем Data Vault. Если упростить, он «режет» модель на очень мелкие части, чтобы изменения в атрибутах и связях можно было добавлять почти без переделок схемы. -✅ **Плюсы**: -- **Максимальная гибкость**: поменяли модель — не трогали старые таблицы; -- **Бесконечная эволюция**: можно добавлять атрибуты «задним числом». +Основные типы таблиц: -❌ **Минусы**: -- Очень сложные запросы (JOIN’ов — десятки); -- Почти не используется «в чистом виде» — чаще как концепция. +* **Anchor** - сущности (например, «клиент» или «заказ»). +* **Attribute** - отдельный атрибут сущности, обычно с историей (например, email, город, статус - каждый в своей таблице). +* **Tie** - связь между сущностями (например, «клиент ↔ заказ»). -📌 **Когда выбирать**: -→ Экспериментальные проекты; -→ Когда схема данных *каждый месяц* радикально меняется. +![Пример Anchor Modeling](images/anchor-model-small.jpg) + +Плюс подхода - высокая гибкость: проще добавлять новые атрибуты и варианты связей. Минус - цена этой гибкости: получается очень много таблиц, и запросы (и поддержка модели) обычно заметно сложнее, огромное кол-во `JOIN`. Для обычного DWH-проекта это точно не первый выбор - скорее вариант для очень динамичных предметных областей, где структура данных часто меняется. --- diff --git a/dwh-modeling/images/3NF-small.jpg b/dwh-modeling/images/3NF-small.jpg new file mode 100644 index 0000000..426c201 Binary files /dev/null and b/dwh-modeling/images/3NF-small.jpg differ diff --git a/dwh-modeling/images/anchor-model-small.jpg b/dwh-modeling/images/anchor-model-small.jpg new file mode 100644 index 0000000..02ee18d Binary files /dev/null and b/dwh-modeling/images/anchor-model-small.jpg differ diff --git a/dwh-modeling/images/data-vault-small.jpg b/dwh-modeling/images/data-vault-small.jpg new file mode 100644 index 0000000..7702bbb Binary files /dev/null and b/dwh-modeling/images/data-vault-small.jpg differ diff --git a/dwh-modeling/images/star-model-small.jpg b/dwh-modeling/images/star-model-small.jpg new file mode 100644 index 0000000..61e38da Binary files /dev/null and b/dwh-modeling/images/star-model-small.jpg differ