Упрощение раздела про DV

This commit is contained in:
2025-11-15 19:08:20 +03:00
parent c66ba776c2
commit bb9902a448
+67 -139
View File
@@ -316,175 +316,103 @@ fact_sales.order_date BETWEEN dim_customer.valid_from AND dim_customer.valid_to
### **3. Data Vault 2.0 — «конструктор Lego» для больших DWH** ### **3. Data Vault 2.0 — «конструктор Lego» для больших DWH**
*Идея: Дэн Линстедт (Dan Linstedt). Цель — собирать DWH из повторно используемых блоков, не боясь, что новый источник «сломает» всё, что было до него.* *Идея: Дэн Линстедт (Dan Linstedt). Цель — так организовать хранилище, чтобы можно было спокойно добавлять новые источники и хранить историю, не ломая старую модель.*
#### С чего начать? Представьте конструктор #### В чём идея, по-человечески
У вас есть коробка Lego. В ней: В Data Vault (DV) все сущности разлетаются по трём типам таблиц:
- **Красные кирпичи (Хабы)** — это *«что или кто»*: клиент, заказ, товар.
У них нет цвета, надписей — только форма (бизнес-ключ). Главное — *узнать*, что это «один и тот же клиент №101», даже если его email менялся трижды.
- **Серые соединители (Линки)** — это *«как связаны»*: «заказ №5001 создан клиентом №101».
Не сами объекты, а *связь между ними*. И даже эту связь можно «отвязать» и привязать по-другому — без пересборки кирпичей.
- **Жёлтые наклейки (Сателлиты)** — это *«какие у них свойства»*: имя клиента, статус заказа, цена товара.
И самое важное: **каждый раз, когда что-то изменилось — наклеиваем новую новую наклейку**, не стирая старую. Так у нас остаётся *полная история*.
💡 **Главный принцип DV**: - **Hub (Хаб)** — *«кто/что это»*.
> *«Идентичность — навсегда. Свойства — меняются. Связи — тоже могут меняться. И всё это — отдельно.»* Только бизнес-ключ и технические поля: клиент, заказ, договор.
```mermaid - **Link (Линк)** — *«как они связаны»*.
erDiagram «Клиент сделал заказ», «договор относится к счёту».
%% Хабы - красные кирпичи (идентичность)
%% Связи между компонентами
HUB_CUSTOMER ||--o{ SAT_CUSTOMER_INFO : "имеет"
HUB_CUSTOMER ||--o{ LINK_ORDER_CUSTOMER : "участвует_в"
HUB_ORDER ||--o{ LINK_ORDER_CUSTOMER : "создан"
LINK_ORDER_CUSTOMER ||--o{ SAT_ORDER_STATUS : "имеет_статус"
HUB_CUSTOMER { - **Satellite (Сателлит)** — *«какие у них свойства и как они менялись»*.
varchar customer_bk PK "Бизнес-ключ: '101'" Имя клиента, email, статус заказа, цены — всё с историей изменений.
varchar record_source
timestamp load_dttm
}
HUB_ORDER {
varchar order_id PK "Бизнес-ключ: '5001'"
varchar record_source
timestamp load_dttm
}
%% Линки - серые соединители (связи)
LINK_ORDER_CUSTOMER {
varchar link_key PK "Хэш от (order_id+customer_bk)"
varchar order_id FK "→ HUB_ORDER"
varchar customer_bk FK "→ HUB_CUSTOMER"
varchar record_source
timestamp load_dttm
}
%% Сателлиты - жёлтые наклейки (атрибуты + история)
SAT_CUSTOMER_INFO {
varchar customer_bk FK "→ HUB_CUSTOMER"
varchar hashdiff
timestamp valid_from
timestamp valid_to
varchar name
varchar email
varchar city
varchar record_source
timestamp load_dttm
}
SAT_ORDER_STATUS {
varchar link_key FK "→ LINK_ORDER_CUSTOMER"
varchar hashdiff
timestamp valid_from
timestamp valid_to
varchar status
varchar record_source
timestamp load_dttm
}
```
> **Как читать схему:** 💡 **Главная мысль:**
> 🔴 **Красные блоки (Хабы)** = «Кто/что это?» — только идентичность, никаких атрибутов. идентичность, связи и атрибуты живут **в разных таблицах**, поэтому:
> ⚪ **Серые блоки (Линки)** = «Как связаны?» — соединяют хабы, фиксируют отношения. - историю проще хранить;
> 🟡 **Жёлтые блоки (Сателлиты)** = «Какие свойства?» — хранят атрибуты + историю изменений. - новые источники проще прикручивать;
> - меньше шансов «сломать» старые отчёты.
> 💡 **Правило конструктора:** Чтобы добавить новый источник (например, мобильное приложение), мы просто «приклеиваем» новый сателлит к существующему хабу — не перестраивая всю модель.
--- ---
#### Почему это не просто SCD Type 2 «по-другому»? #### Чем DV отличается от 3NF и Звезды
В SCD Type 2 (в `dim_customer`) мы *смешиваем*: Если сильно упростить:
- идентичность (`customer_bk = 101`),
- и атрибуты (`email`, `city`),
- и связь с бизнес-событиями (`valid_from`, `is_current`).
В Data Vault эти три вещи **разнесены по разным таблицам**: - В **3NF/Звезде** мы часто смешиваем:
- `hub_customer` — только `customer_bk` и технические поля (откуда пришёл, когда загрузили); - бизнес-ключ,
- `sat_customer_info` — только атрибуты + их история (как в SCD, но отдельно!); - текущие атрибуты,
- `link_order_customer` — только «кто сделал заказ» (и даже тут — отдельный сателлит может хранить *статус связи*: «активный», «отменённый» и т.д.). - историю (SCD2)
— всё это в одной таблице измерения.
➡️ Это даёт **огромный бонус**: - В **Data Vault** это *разнесено*:
Если завтра пришёл новый источник — например, мобильное приложение — и там у клиента есть `device_id`, - Hub — только бизнес-ключ;
вы **не перестраиваете `dim_customer`** (как в Kimball/3NF), - Satellite — только атрибуты + история;
а просто добавляете **новый сателлит**`sat_customer_device`. - Link — только связи между сущностями.
Старые отчёты продолжают работать. Новые — используют новую наклейку.
За это приходится платить сложностью модели и количеством таблиц. Зато DV хорошо выдерживает:
- много разнородных источников;
- «грязные» данные;
- жёсткие требования по аудиту и трассировке.
--- ---
#### Как устроен «сырой» Data Vault (упрощённо) #### Raw Vault и Business Vault — два слоя
| Таблица | Внутри | Пример | Часто говорят «Raw Vault» и «Business Vault». Грубо:
|---------|--------|--------|
| **`hub_customer`** | `customer_bk` (например, `'101'`) + `load_dttm` + `source` | Клиент «101» появился в CRM 10 января |
| **`sat_customer_info`** | `customer_bk`, `email`, `city`, `valid_from`, `valid_to`, `load_dttm` | 10 янв–15 мая: `a@ex.com`, Москва; 16 мая–…: `b@ex.com`, Москва |
| **`hub_order`** | `order_id` + `load_dttm` + `source` | Заказ «5001» из системы заказов |
| **`link_order_customer`** | `order_id`, `customer_bk` + `load_dttm` + `source` | Заказ 5001 → клиент 101 |
| **`sat_order_status`** *(опционально)* | `order_id`, `status`, `valid_from`, `valid_to` | 10 янв: «оплачен», 12 янв: «доставлен» |
> ⚠️ *На практике вместо `customer_bk` часто используют **хэш-ключ** (`hk_customer`) — чтобы сравнивать быстрее и избежать проблем с типами (число vs строка). - **Raw Vault** — «как прилетело из источников».
Хабы, линкы и сателлиты, максимально близкие к исходным данным.
Задача: надёжно собрать и сохранить **полную историю**.
- **Business Vault** — «как удобно считать дальше».
На основе Raw Vault появляются:
- служебные таблицы (PIT, Bridge и т.п.),
- подготовленные представления под витрины и отчёты,
- бизнес-правила (например, что считать «активным клиентом»).
Дальше поверх этого уже строятся **обычные витрины в формате Звезды**, с которыми работают аналитики.
Если примерить это к классическим слоям `stg → ods → dds → dm`, то **очень грубо** можно думать так:
- `stg` всё равно остаётся как «приземление» (landing) из источников;
- **Raw Vault** по духу ближе к **ODS**: мало бизнес-логики, зато полная история и интеграция из разных систем;
- **Business Vault** ближе к **DDS**: здесь уже живут бизнес-правила и подготовка данных к витринам;
- `dm` по-прежнему остаётся витринами в формате Звезды, с которыми работают аналитики и BI.
Важно: это именно *аналогия для понимания*, а не жёсткое правило проектирования.
--- ---
#### А как же отчёты? Где витрины? #### Когда DV вам, скорее всего, рано
Хороший вопрос. **Сырой DV — не для BI.** Это «склад запчастей». Если у вас:
Чтобы собрать «машину», нужен второй шаг: **Business Vault** (в DV 2.0 это — обязательная часть!).
Там уже: - 25 источников,
- **PIT-таблицы (Point-in-Time)** — «какой клиент был 12 января 2024?» за 1 JOIN, а не за 5 оконных функций; - небольшая команда (1–2 инженера + аналитик),
- **Bridge-таблицы** — готовые пути: «заказ → клиент → последняя версия профиля»; - задачи уровня «сделать первые отчёты»,
- **Derived-таблицы** — после бизнес-логики (скидки, сегментация, флаги).
А *уже из них* строят **витрины в формате Звезды** — те самые `mart_daily_sales`, которые вы подключаете в Power BI. то **Data Vault почти наверняка избыточен**.
Чаще всего хватает связки:
🔁 То есть цепочка: > `stg → ods → dds (3NF или простая Звезда с SCD2) → dm (Звезда)`
**Источник → Hub/Link/Sat (Raw DV) → PIT/Bridge (Business Vault) → Star Schema (DM)**
Можно строить и напрямую, без PIT/Bridge таблиц. Но это значительно "тяжелее" с точки зрения затрат вычислительных ресурсов.
--- ---
#### Плюсы и минусы — честно и без прикрас #### Что важно запомнить из этой статьи
| ✅ Плюсы | ❌ Минусы | Для этой статьи достаточно:
|---------|----------|
| **История «из коробки»** — каждое изменение видно, ничего не перезаписывается | Сырой слой тяжел для чтения — нужен Business Vault (доп. работа) |
| **Добавить источник — легко** (новый сателлит, не ломая старое) | **Новых таблиц много** (Hub/Link/Sat — уже 3 на простую сущность) |
| **Полная трассировка**: кто, откуда, когда привёз каждую строчку | **Требует дисциплины**: если `record_source` забыли — аудит сломан |
| **Параллельная работа**: одна команда — клиенты, другая — заказы | **Не для MVP**: окупается на 10+ источниках, не на двух CSV |
--- - знать, что **Data Vault** — это способ строить хранилище как **конструктор из Hub/Link/Satellite**,
- понимать, что он нужен в первую очередь там, где:
- много систем-источников,
- нужна *полная* история и прозрачный аудит.
#### Когда Data Vault — ваш выбор? Детали (Raw vs Business Vault, PIT/Bridge, DV 1.0 vs 2.0 и т.п.) — это уже тема для отдельной, взрослой статьи.
| Выберите DV 2.0, если… | Не начинайте с DV, если… |
|------------------------|---------------------------|
| У вас 5+ разнородных систем (CRM, ERP, мобильные приложения, внешние API) | У вас 1–2 источника и нужно быстро дать отчёт |
| Схемы часто меняются (новые атрибуты, новые связи) | Схема стабильна (например, учёт договоров в банке) |
| Важен аудит: «кто и когда изменил email?» (финтех, госсектор) | Отчёты — главная цель, а не соответствие регуляторам |
| В будущем — масштабирование: новые домены, новые команды | Вы один или вдвоём, и хотите простоты |
> 🎯 **Совет для новичка**:
> Пока учитесь — *не пытайтесь собрать DV вручную*. Но **понимать его логику — обязательно**.
> Почему? Потому что многие современные enterprise-DWH сегодня — либо DV, либо гибриды (DV + Star).
> Даже если вы будете работать с витринами — вы будете *понимать*, откуда берутся данные и почему история «не обновляется».
---
#### Важно: DV 1.0 vs DV 2.0 — в чём разница?
- **DV 1.0** — только Hub/Link/Sat + историзация через `load_dttm`.
*Проблема:* нет стандартного способа хранить *периоды действия* (как в SCD Type 2) — `valid_from/valid_to` приходилось изобретать самим.
- **DV 2.0** — стандартизирует:
- **Effectivity Satellites** (с `valid_from/valid_to`) — для явной историчности,
- **Multi-Active Satellites** — когда у объекта *несколько одновременных значений* (например, три активных телефона),
- **Business Vault** — как обязательный слой перед витринами.
➡️ Сегодня, когда говорят «Data Vault», почти всегда имеют в виду **DV 2.0**.
--- ---