From aa3ebbfd7c6b39e0d997f67a875a77c5b82abbf9 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 15 Nov 2025 20:47:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82?= =?UTF-8?q?=D1=83=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dwh-modeling/DataVault.md | 438 ++++++++++++++++++-------------------- 1 file changed, 210 insertions(+), 228 deletions(-) diff --git a/dwh-modeling/DataVault.md b/dwh-modeling/DataVault.md index aafee6d..162043b 100644 --- a/dwh-modeling/DataVault.md +++ b/dwh-modeling/DataVault.md @@ -1,6 +1,16 @@ # **Data Vault 2.0: как собрать хранилище как конструктор** -*Для тех, кто уже слышал про STG/ODS/DDS/DM, факты/измерения и SCD, но хочет разобраться, что такое Data Vault и зачем он вообще нужен.* +## 📚 Оглавление + +1. [Зачем вообще нужен Data Vault?](#1-зачем-вообще-нужен-data-vault) +2. [Интуиция: DV как конструктор Lego](#2-интуиция-dv-как-конструктор-lego) +3. [Три типа таблиц в Data Vault 2.0](#3-три-типа-таблиц-в-data-vault-20) +4. [Типы сателлитов в DV 2.0](#4-типы-сателлитов-в-dv-20) +5. [Raw Vault и Business Vault](#5-raw-vault-и-business-vault) +6. [Пример: клиент и заказы в DV-стиле](#6-пример-клиент-и-заказы-в-dv-стиле) +7. [Как это живёт в пайплайне загрузки](#7-как-это-живёт-в-пайплайне-загрузки) +8. [Плюсы и минусы Data Vault](#8-плюсы-и-минусы-data-vault) +9. [Когда DV стоит использовать, а когда нет](#9-когда-dv-стоит-использовать-а-когда-нет) --- @@ -41,43 +51,43 @@ * 🔴 **Hub (Хаб)** — *«кто/что это»* Сущности: клиент, заказ, договор, счёт. - Внутри: бизнес-ключ (`customer_id`, `contract_number`) + техполя. + Внутри: бизнес‑ключ (например, customer_id или contract_number) и техполя. * ⚪ **Link (Линк)** — *«как они связаны»* «Клиент сделал заказ», «договор относится к счёту». - Внутри: ссылки на хабы + техполя. + Внутри: ссылки на хабы и техполя. * 🟡 **Satellite (Сателлит)** — *«какие у них свойства и как они менялись»* - Атрибуты сущности (имя, email, статус, тариф) + история изменений. + Атрибуты сущности (имя, email, статус, тариф) плюс история изменений. Главная идея: > **Идентичность, связи и атрибуты живут отдельно.** > Тогда изменения в одном не ломают другое. -На картинке это выглядит примерно так: +На картинке это можно показать так: ```mermaid 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 ||--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 { - varchar customer_bk PK "Бизнес-ключ: '101'" + varchar customer_bk PK varchar record_source timestamp load_dttm } HUB_ORDER { - varchar order_id PK "Бизнес-ключ: '5001'" + varchar order_id PK varchar record_source timestamp load_dttm } LINK_ORDER_CUSTOMER { - varchar link_key PK "Хэш (order_id + customer_bk)" + varchar link_key PK varchar order_id FK varchar customer_bk FK varchar record_source @@ -109,11 +119,9 @@ erDiagram Как это читать: -* 🔴 **HUB_CUSTOMER / HUB_ORDER** — «этот клиент существует», «этот заказ существует»; -* ⚪ **LINK_ORDER_CUSTOMER** — «именно этот заказ сделал именно этот клиент»; -* 🟡 **SAT_…** — как менялись атрибуты (email, статус и т.п.) во времени. - ---- +* 🔴 HUB_CUSTOMER / HUB_ORDER — «этот клиент существует», «этот заказ существует»; +* ⚪ LINK_ORDER_CUSTOMER — «именно этот заказ сделал именно этот клиент»; +* 🟡 SAT_… — как менялись атрибуты (email, статус и т.п.) во времени. ## 3. Три типа таблиц в Data Vault 2.0 @@ -123,24 +131,24 @@ erDiagram **Hub** содержит: -* бизнес-ключ (`customer_bk`, `order_id`, `contract_number`); +* бизнес‑ключ (customer_bk, order_id, contract_number); * техническую информацию: - * `record_source` — из какой системы пришла первая запись; - * `load_dttm` — когда попала в DV; - * иногда — хэш бизнес-ключа (`hk_customer`). + * record_source — из какой системы пришла первая запись; + * load_dttm — когда запись попала в DV; + * иногда — хэш бизнес‑ключа (hk_customer). Главные правила: -* **один бизнес-ключ — один хаб** (одна строка на сущность, без истории); +* один бизнес‑ключ — один хаб (одна строка на сущность, без истории); * хаб не знает про атрибуты (имя, email) — только идентичность. -Простейший DDL-скелет: +Простейший DDL‑скелет: ```sql CREATE TABLE hub_customer ( - hk_customer BYTEA PRIMARY KEY, -- хэш от BK - customer_bk VARCHAR(50) NOT NULL, -- business key + hk_customer BYTEA PRIMARY KEY, -- хэш от BK + customer_bk VARCHAR(50) NOT NULL, -- business key record_source VARCHAR(50) NOT NULL, load_dttm TIMESTAMP NOT NULL ); @@ -150,16 +158,16 @@ CREATE TABLE hub_customer ( **Link** описывает факт связи, например: -* заказ ↔ клиент, -* договор ↔ счёт, +* заказ ↔ клиент; +* договор ↔ счёт; * карта ↔ клиент. -Примеры бизнес-смыслов: +Примеры бизнес‑смыслов: -* `link_order_customer` — «этот заказ принадлежит этому клиенту»; -* `link_contract_account` — «этот договор привязан к этому счёту». +* link_order_customer — «этот заказ принадлежит этому клиенту»; +* link_contract_account — «этот договор привязан к этому счёту». -DDL-приблизительно: +DDL‑эскиз: ```sql CREATE TABLE link_order_customer ( @@ -180,17 +188,17 @@ CREATE TABLE link_order_customer ( Примеры: -* `sat_customer_info` — имя, email, город клиента; -* `sat_customer_segment` — сегмент, категория, риск-профиль; -* `sat_order_status` — статус заказа. +* sat_customer_info — имя, email, город клиента; +* sat_customer_segment — сегмент, категория, риск‑профиль; +* sat_order_status — статус заказа. Типичные поля: -* ссылка на HUB/LINK (`hk_customer`, `hk_order_customer`); -* атрибуты (email, city, status…); -* `valid_from` / `valid_to` — период действия версии; -* `hashdiff` — хэш от всех атрибутов (чтобы понимать, что строка действительно изменилась, а не повторилась); -* `record_source`, `load_dttm`. +* ссылка на HUB или LINK (hk_customer, hk_order_customer); +* атрибуты (email, city, status и т.п.); +* valid_from / valid_to — период действия версии; +* hashdiff — хэш от всех атрибутов, чтобы понять, изменилась ли строка; +* record_source, load_dttm. ```sql CREATE TABLE sat_customer_info ( @@ -206,15 +214,15 @@ CREATE TABLE sat_customer_info ( ); ``` ---- +Главная мысль: DV заставляет явно разделять идентичность, связи и атрибуты с историей. Это делает модель сложнее на вид, но гораздо устойчивее к изменениям источников. ## 4. Типы сателлитов в DV 2.0 В DV 2.0 появилось разделение по «ролям» сателлитов. Главное, что стоит знать: * **Descriptive Satellites** — обычные атрибуты (имя, адрес, тариф) с историей. -* **Effectivity Satellites** — фокус на периодах действия (`valid_from/valid_to`), очень похоже на SCD2. -* **Multi-Active Satellites** — когда у сущности **несколько одновременных** значений (например, три активных телефона клиента). +* **Effectivity Satellites** — фокус на периодах действия (`valid_from` / `valid_to`), очень похоже на SCD2. +* **Multi-Active Satellites** — когда у сущности несколько одновременных значений (например, три активных телефона клиента). * **Transactional Satellites** — события, привязанные к одному хабу/линку (например, журнал изменений статуса). На практике это разные DDL-«шаблоны» поверх одной и той же идеи: @@ -222,253 +230,258 @@ CREATE TABLE sat_customer_info ( --- -## 5. Raw Vault vs Business Vault: «склад деталей» и «сборочный цех» +## 5. Raw Vault и Business Vault Обычно под «Data Vault» люди смешивают два слоя: ```mermaid flowchart LR SRC[Источники] --> STG[STG / ODS] - STG --> RAW[Raw Vault
Hubs, Links, Sats] - RAW --> BV[Business Vault
PIT, Bridge, Derived] - BV --> DM[Data Marts
Star Schema] - DM --> BI[BI / reports / ML] -```` + STG --> RAW[Raw Vault +Hubs, Links, Sats] + RAW --> BV[Business Vault +PIT, Bridge, Derived] + BV --> DM[Data Marts +Star Schema] + DM --> BI[BI / ML] +``` -* **Raw Vault** — это *про приём и хранение* данных «как есть», но в форме Hub/Link/Sat. -* **Business Vault** — это *про приведение их в «деловой» вид*: с бизнес-правилами, PIT/Bridge и подготовленными представлениями. +* **Raw Vault** — это про приём и хранение данных «как есть», но уже в форме Hub / Link / Satellite. +* **Business Vault** — это про приведение этих данных в более «деловой» вид: с бизнес-правилами, PIT/Bridge и подготовленными представлениями. ### 5.1. Raw Vault — «всё прилетевшее, аккуратно разложенное по ящичкам» -**Raw DV** — первый слой поверх STG/ODS: +Raw DV — первый слой поверх STG / ODS: * выравниваем ключи; -* разбираем сущности по Hub/Link/Sat; -* сохраняем *всю* историю изменений, не решая ещё «что такое активный клиент» или «успешный заказ». +* разбираем сущности по Hub / Link / Sat; +* сохраняем всю историю изменений, не решая ещё, что такое «активный клиент» или «успешный заказ». Характерные черты Raw Vault: * минимум бизнес-логики: - никаких «клиент активен, если было ≥1 покупки за 90 дней»; + + * никаких правил вроде «клиент активен, если была хотя бы одна покупка за 90 дней»; * все источники показываются «как есть», только приведены к общим ключам; -* структура стабильна: добавился новый источник → появился новый Sat к тому же Hub. - -Это слой **для инженеров**. Писать по нему отчёты — больно: - -* чтобы узнать «какой у клиента email на дату заказа», нужно JOIN’ить Hub + Sat + Link, плюс фильтровать по `valid_from/valid_to` или `load_dttm`; -* чтобы собрать «портрет клиента» — нужно руками клеить несколько сателлитов. - -Поэтому **Raw DV почти никогда не является точкой входа для аналитиков**. - ---- +* структура стабильна: добавился новый источник → появился новый Satellite к тому же Hub. ### 5.2. Business Vault — «там, где из Lego собирают модули» -**Business Vault (BV)** — это слой поверх Raw DV, где: +Business Vault (BV) — следующий слой над Raw DV: -* появляются **бизнес-правила**, -* строятся удобные для чтения **«сборные» объекты** (таблицы и представления), -* упрощается доступ к истории. +* здесь применяются бизнес-правила (что считать активным клиентом, как трактовать статусы); +* здесь строятся вспомогательные структуры: -Кто потребитель BV: + * PIT-таблицы, + * Bridge-таблицы, + * агрегаты и derived-таблицы. -* разработчики витрин (DM / Star Schema); -* часть сложных отчётов (особенно с тяжёлой историей); -* иногда — data scientists, если им нужен богатый, но ещё не «сплющенный» слой. +Именно из BV чаще всего строятся витрины в формате Звезды, к которым подключаются BI и отчётность. -В BV живут несколько типичных конструкций. +Если сильно упростить: + +* Raw DV → «мы всё собрали»; +* Business DV → «мы это привели в вид, с которым удобно жить»; +* DM → «мы вынесли это на витрину в понятной форме». #### 5.2.1. PIT-таблицы (Point-in-Time) -**PIT (Point-in-Time)** — таблицы, которые отвечают на вопрос: +PIT (Point-in-Time) отвечает на вопрос: -> «Как выглядел объект *на дату X*?» +> Как объект выглядел на дату X? -Вместо того чтобы каждый раз писать сложный запрос с диапазонами (`valid_from/valid_to`), мы заранее готовим таблицу: +Вместо того чтобы каждый раз писать сложные запросы с диапазонами `valid_from` / `valid_to`, мы заранее готовим таблицу с нужными ссылками на версии сателлитов. + +Простейший эскиз: ```sql CREATE TABLE pit_customer_daily ( - hk_customer BYTEA, - as_of_date DATE, - hk_sat_info BYTEA, -- ссылка на нужную версию sat_customer_info - hk_sat_segment BYTEA, -- ссылка на нужную версию sat_customer_segment - ... - load_dttm TIMESTAMP + hk_customer BYTEA, + as_of_date DATE, + hk_sat_info BYTEA, -- ссылка на нужную версию sat_customer_info + hk_sat_segment BYTEA, -- ссылка на нужную версию sat_customer_segment + load_dttm TIMESTAMP ); ``` -Теперь, чтобы собрать витрину продаж: - -* JOIN `fact_orders` к `pit_customer_daily` по `order_date = as_of_date`; -* а уже потом — к сателлитам по их ключам. - -Выигрыш: - -* сложная логика выбора «правильной версии на дату» живёт в одном месте (ETL PIT); -* BI и витрины видят «почти плоский» слой. +Теперь, чтобы собрать витрину продаж, достаточно один раз присоединить PIT по дате. #### 5.2.2. Bridge-таблицы -**Bridge** — это «готовые маршруты» по графу Hub/Link. +Bridge-таблицы помогают проходить по сложным цепочкам связей: -Например: +* от клиента ко всем его договорам; +* от договора ко всем счетам; +* от счёта ко всем транзакциям. -* в DV клиент ↔ договор ↔ счёт ↔ продукт живут в разных хабах/линках; -* чтобы каждый раз не JOIN’ить весь путь, мы строим `bridge_customer_account`: - -```sql -CREATE TABLE bridge_customer_account AS -SELECT DISTINCT - hk_customer, - hk_account, - first_seen_dttm, - last_seen_dttm -FROM ... -``` - -Bridge: - -* упрощают запросы для витрин; -* фиксируют сложные правила связи (например, что считать «текущим» счётом клиента). +Вместо того чтобы каждый раз писать длинный JOIN по нескольким Links, мы один раз строим Bridge и далее используем его как предрасчитанный путь. #### 5.2.3. Business-правила и derived-таблицы В BV логично размещать бизнес-логику, которая: -* **повторяется** во многих отчётах; -* **стабильна** относительно конкретной витрины. +* повторяется во многих отчётах; +* достаточно стабильна. Примеры: -* «Активный клиент» — флаг, который вычисляется на основе Raw DV (истории покупок, логинов и т.п.); -* «Основной тариф» — выбран по набору правил из нескольких источников; -* «Чистый статус заказа» — свёрнут из цепочки статусов (created → paid → shipped → delivered / cancelled). +* флаг «активный клиент», который вычисляется на основе истории покупок и логинов; +* «основной тариф», выбранный по набору правил из нескольких источников; +* «чистый статус заказа», свёрнутый из цепочки статусов (created → paid → shipped → delivered / cancelled). -Это могут быть как отдельные Sats/Links, так и «логические» таблицы BV: - -```sql -CREATE TABLE bv_customer_flags AS -SELECT - hk_customer, - is_active_30d, - is_active_90d, - is_vip, - load_dttm -FROM ... -``` - -Потом витрины берут уже готовые флаги, не дублируя правила. - ---- +Это могут быть как отдельные Satellites / Links, так и логические таблицы BV с уже посчитанными флагами и агрегатами. ### 5.3. Граница между Business Vault и витринами (DM) -Важно не скатиться в две крайности: +Важно проговорить границу: -* всё тащить в Raw DV → BV пустой, витрины перегружены логикой; -* всё тащить в BV → витрины превращаются в тонкий слой SELECT’ов, но BV — новый «монолит». +* Business Vault — ещё про данные и историю; +* DM (Data Marts) — уже про конкретные бизнес-сценарии и удобство BI. -Полезное правило: - -> **В Business Vault живёт то, что относится к бизнес-сущностям и повторяется. -> В витринах живёт то, что уникально для конкретного отчёта/дашборда.** - -Например: - -* «клиент активен, если ≥1 покупки за 90 дней» — это логика уровня клиента → место ей в BV (`bv_customer_flags`); -* «клиент попал в эту конкретную маркетинговую воронку» — это логика конкретного отчёта → можно оставить в DM. - ---- +Витрины можно переделывать, не трогая BV, пока вы не меняете фундаментальные бизнес-правила. ### 5.4. Как выглядит связка Raw DV → BV → DM на примере -Возьмём пример интернет-магазина: +Мини-пример интернет-магазина: -1. **Raw Vault**: +1. Raw Vault: * `hub_customer`, `hub_order`; * `link_order_customer`; * `sat_customer_info`, `sat_order_status`, `sat_customer_segment`. -2. **Business Vault**: +2. Business Vault: - * `pit_customer_daily` — «срез клиента по дням»; + * `pit_customer_daily` — срез клиента по дням; * `bv_customer_flags` — активность, VIP-статусы, сегменты; * `bridge_customer_order` — связи клиент ↔ заказ с удобными ключами. -3. **DM / Star Schema**: +3. DM / Star Schema: * `dm.fact_sales` — факт продаж; - * `dm.dim_customer` — уже «плоское» измерение с нужными полями (`email_current`, `segment`, `is_active_90d`…); - * `dm.dim_date`, `dm.dim_product` и т.п. + * `dm.dim_customer` — уже плоское измерение с нужными полями (email_current, segment, is_active_90d и т.п.); + * `dm.dim_date`, `dm.dim_product` и другие измерения. В результате: -* **Raw DV** — технически правильный, историчный и некрасивый; -* **BV** — «рабочий слой для инженеров и продвинутых аналитиков»; -* **DM** — привычная Звезда для всех остальных. - ---- - -Кратко: - -* Raw DV без BV — это как держать только структуры `hub_*/link_*/sat_*` и заставлять всех писать поверх них запросы. Это больно. -* **Business Vault — обязательный промежуточный слой**, если вы действительно живёте в Data Vault, а не просто «сложили историю по паттерну Hub/Link/Sat». - ---- +* Raw DV — технически корректный, историчный и некрасивый слой; +* BV — рабочий слой для инженеров и продвинутых аналитиков; +* DM — привычная Звезда для всех остальных. ## 6. Пример: клиент и заказы в DV-стиле -Возьмём мини-пример (тот же интернет-магазин): +Возьмём мини‑пример всё того же интернет‑магазина. -* клиент с `customer_id = 101` и меняющимся email; -* заказы `order_id = 5001, 5002`; -* статусы заказов. +У нас есть: -В Data Vault: +* клиент с `customer_id = 101`, у которого иногда меняется email и город; +* два заказа: `order_id = 5001` и `order_id = 5002`; +* статусы заказов: `created → paid → shipped → delivered`. -* `hub_customer` — одна строка на BK `101`; -* `sat_customer_info` — несколько строк по мере смены email/города; -* `hub_order` — по строке на каждый заказ; -* `link_order_customer` — связь заказ ↔ клиент; +### Что появляется в Raw Vault + +В Data Vault это раскладывается на несколько таблиц: + +* `hub_customer` — по одной строке на каждого клиента (BK = `customer_id`). +* `hub_order` — по одной строке на каждый заказ (BK = `order_id`). +* `link_order_customer` — связь «какой заказ сделал какой клиент». +* `sat_customer_info` — история атрибутов клиента (имя, email, город). * `sat_order_status` — история статусов заказа. -Дальше: +Примерно так это выглядит логически: -* из Raw DV мы строим PIT: +```text +HUB_CUSTOMER +-------------------------------------- +customer_bk | record_source | load_dttm +-------------------------------------- +101 | CRM | 2023-01-10 10:00 - * «каким был клиент на дату заказа?»; -* и уже из PIT + ссылок собираем витрину `mart_sales` в формате Звезды. +SAT_CUSTOMER_INFO +--------------------------------------------------------------------- +customer_bk | valid_from | valid_to | email | city +--------------------------------------------------------------------- +101 | 2023-01-10 | 2023-06-01 | a@example.com | Moscow +101 | 2023-06-01 | 9999-12-31 | alice@newmail.com | Moscow -Тут важно, что **Raw DV почти не трогается** при изменении бизнес-логики — правим BV и витрины. +HUB_ORDER +-------------------------------------- +order_id | record_source | load_dttm +-------------------------------------- +5001 | SHOP | 2023-06-10 12:00 +5002 | SHOP | 2023-06-11 09:30 ---- +SAT_ORDER_STATUS +---------------------------------------------------------------- +order_id | valid_from | valid_to | status +---------------------------------------------------------------- +5001 | 2023-06-10 | 2023-06-10 | created +5001 | 2023-06-10 | 2023-06-11 | paid +5001 | 2023-06-11 | 9999-12-31 | shipped +... | ... | ... | ... +``` + +Ключевая идея: **любое изменение** (email, статус) — это **новая строка** в соответствующем Satellite. + +### Как из этого получить витрину продаж + +Дальше нам нужно привычное измерение `dim_customer` и факт `fact_sales` в формате Звезды. + +Обычно цепочка выглядит так: + +1. В Business Vault строим `PIT`‑таблицу по клиентам: + + * для каждой даты (или дня, или часа) знаем, какая строка из `sat_customer_info` была актуальна. +2. Строим витрину `dm.dim_customer`: + + * на выбранную дату берём нужную версию из `sat_customer_info`; + * добавляем флаги/сегменты из других Satellites/BV‑таблиц. +3. Строим факт `dm.fact_sales`, где каждая строка — заказ или позиция заказа. + +Итог: на витрине мы видим «плоского» клиента (одна строка → текущее имя/город/email на момент заказа), +хотя внутри DV лежит полная, аккуратно разложенная история. ## 7. Как это живёт в пайплайне загрузки -Типичный ETL/ELT с DV: +Посмотрим теперь, как DV вписывается в обычный ETL/ELT‑пайплайн. -1. **STG/ODS**: вытащили данные из источников, почистили типы, привели формат. -2. **Raw Vault**: +Типичный поток выглядит так: - * по BK вычислили хэш-ключи для Hubs; - * создали/обновили Hubs; - * создали/обновили Links; - * сравнили `hashdiff` в Sats → добавили новые версии атрибутов. -3. **Business Vault**: +1. **STG / ODS — приём и первичная обработка** - * собрали PIT-таблицы (одна строка на объект на дату X); - * добавили бизнес-флаги и derived-поля. -4. **DM (Star)**: + * Подключаемся к источникам (CRM, биллинг, сайт, партнёрские выгрузки). + * Забираем инкременты (CDC, выгрузки по расписанию, API). + * Приводим типы данных, чистим очевидный мусор, нормализуем форматы дат и т.п. - * построили факт + измерения, которые уже подходят BI/аналитикам. +2. **Raw Vault — приземление в Hub / Link / Satellite** -За счёт **хэш-ключей и hashdiff** DV хорошо масштабируется и параллелится: -разные сущности и домены могут грузиться независимыми пайплайнами. + * Из STG/ODS считаем хэш‑ключи для бизнес‑ключей (HK для Hubs). + * Создаём/обновляем **Hubs** — если бизнес‑ключ новый, заводим запись. + * Создаём/обновляем **Links** — фиксируем связи между сущностями. + * Для **Satellites** считаем `hashdiff` по атрибутам и добавляем новые строки + только если что‑то реально изменилось. ---- +3. **Business Vault — бизнес‑правила и ускорители** -## 8. Плюсы и минусы Data Vault — без романтики + * Строим PIT‑таблицы, чтобы быстро получать срез «на дату X». + * Строим Bridge‑таблицы для сложных цепочек связей. + * Вычисляем стабильные бизнес‑флаги и derived‑атрибуты (активность, сегменты, статусы). + +4. **DM / Star Schema — витрины для отчётов и аналитики** + + * На основе BV собираем факты и измерения в формате Звезды. + * Под это уже настраиваются BI‑инструменты, отчётность, дашборды. + +Чем это отличается от классического «STG → ODS → DDS → DM»: + +* слой DDS в DV‑подходе часто фактически превращается в **Raw+Business Vault**; +* вместо одной «большой» нормализованной схемы ядра у нас набор Lego‑модулей (Hubs/Links/Sats); +* за счёт хэш‑ключей и независимой загрузки доменов пайплайны проще масштабировать + и параллелить по командам. + +DV не отменяет STG/ODS/DM — он скорее **раскладывает слой DDS на более мелкие и управляемые детали**. + +## 8. Плюсы и минусы Data Vault ### 8.1. Плюсы @@ -487,7 +500,7 @@ FROM ... ### 8.2. Минусы * 🧠 **Высокий порог входа** - Нужно понимать SCD, хэш-ключи, нагрузку на JOIN, паттерны загрузки. + Нужно понимать SCD, хэш‑ключи, нагрузку на JOIN, паттерны загрузки. * 📈 **Больше таблиц и JOIN’ов** Даже простой запрос превращается в «HUB + LINK + 2–3 SAT + PIT». @@ -498,9 +511,7 @@ FROM ... * ⏳ **Плохо подходит для MVP** Для 2–3 источников DV обычно дороже, чем классическая 3NF/Звезда. ---- - -## 9. Когда DV стоит использовать, а когда — нет +## 9. Когда DV стоит использовать, а когда нет ### Подходит, если: @@ -521,32 +532,3 @@ FROM ... > `stg → ods → dds (3NF/простая Звезда с SCD2) → dm (Звезда)` А DV оставить как следующий шаг, когда появятся реальные боли, которые он решает. - ---- - -## 10. Как учить Data Vault дальше - -Если после этой статьи хочется «копнуть глубже», можно идти по такой траектории: - -1. **Повторить базу**: - - * слои STG/ODS/DDS/DM; - * факты/измерения; - * SCD Type 2. - -2. **Почитать/посмотреть про DV 2.0**: - - * книги/доки Линстедта (Dan Linstedt, *Data Vault 2.0*), - * практические доклады (особенно от телекомов и банков — там DV живой). - -3. **Сделать игрушечный DV-проект**: - - * взять тот же интернет-магазин, - * смоделировать `hub_customer`, `hub_order`, `link_order_customer`, 2–3 сателлита, - * написать пару запросов: «какой был клиент на дату заказа?», «как менялся статус заказа?». - -4. **Посмотреть на гибриды**: - - * DV в ядре (Raw+Business Vault), - * Звезда на витринах. -