Чистка заголовков

This commit is contained in:
2025-11-15 21:20:52 +03:00
parent b2ae216b07
commit 71d885a9db
+31 -30
View File
@@ -1,9 +1,9 @@
# **Хранилище данных: как устроена аналитика «под капотом»** # Хранилище данных: как устроена аналитика «под капотом»
*Для тех, кто знает SQL, но хочет понять, как хранить данные не в Excel, а по-взрослому* *Для тех, кто знает SQL, но хочет понять, как хранить данные не в Excel, а по-взрослому*
--- ---
## **Что вы уже умеете — и что узнаете здесь** ## Что вы уже умеете — и что узнаете здесь
✅ Уже знаете: ✅ Уже знаете:
- `SELECT`, `JOIN`, `GROUP BY`; - `SELECT`, `JOIN`, `GROUP BY`;
@@ -24,7 +24,7 @@
--- ---
## **1. Введение: почему нельзя просто SELECT из базы заказов?** ## 1. Введение: почему нельзя просто SELECT из базы заказов?
Представьте: вы — аналитик в интернет-магазине. Вам нужно ответить на вопрос: Представьте: вы — аналитик в интернет-магазине. Вам нужно ответить на вопрос:
> **«Сколько заказов сделал клиент с email `a@ex.com` за 2023 год, и сколько он потратил?»** > **«Сколько заказов сделал клиент с email `a@ex.com` за 2023 год, и сколько он потратил?»**
@@ -45,7 +45,7 @@
--- ---
## **2. Учебный пример: интернет-магазин** ## 2. Учебный пример: интернет-магазин
Чтобы всё было на пальцах — разберём простой, но живой пример. Чтобы всё было на пальцах — разберём простой, но живой пример.
@@ -70,7 +70,7 @@
--- ---
## **3. Зачем делить DWH на слои?** ## 3. Зачем делить DWH на слои?
Представьте, что вы строите дом. Вы же не будете сразу вбивать гвозди в стены — сначала: Представьте, что вы строите дом. Вы же не будете сразу вбивать гвозди в стены — сначала:
1. Привезли стройматериалы (песок, доски, кирпич) — **сырьё**; 1. Привезли стройматериалы (песок, доски, кирпич) — **сырьё**;
@@ -121,7 +121,7 @@ flowchart TD
--- ---
## **4. Путешествие данных: от STG до DM** ## 4. Путешествие данных: от STG до DM
Давайте проследим, как превращается строка заказа. Давайте проследим, как превращается строка заказа.
@@ -189,7 +189,7 @@ flowchart TD
--- ---
## **5. Базовые понятия: факты, измерения, SCD** ## 5. Базовые понятия: факты, измерения, SCD
Представьте отчёт: Представьте отчёт:
> *«10 января 2024 года клиент из Москвы (сегмент Premium) купил Phone за 100 ₽»*. > *«10 января 2024 года клиент из Москвы (сегмент Premium) купил Phone за 100 ₽»*.
@@ -245,7 +245,7 @@ erDiagram
} }
``` ```
### **SCD Type 2 — как хранить историю** ### SCD Type 2 — как хранить историю
Клиент №101: Клиент №101:
- с 1 янв по 15 мая — `email = a@ex.com`, `city = Москва`; - с 1 янв по 15 мая — `email = a@ex.com`, `city = Москва`;
@@ -272,11 +272,11 @@ fact_sales.order_date BETWEEN dim_customer.valid_from AND dim_customer.valid_to
--- ---
## **6. Модели данных для слоя DDS: 4 подхода — и когда какой выбрать** ## 6. Модели данных для слоя DDS: 4 подхода — и когда какой выбрать
В DDS мы можем хранить данные по-разному. Это не «правильно/неправильно», а **выбор под задачу**. В DDS мы можем хранить данные по-разному. Это не «правильно/неправильно», а **выбор под задачу**.
### **1. 3NF (третья нормальная форма)** ### 1. 3NF (третья нормальная форма)
*Источник: Билл Инмон (Bill Inmon)* *Источник: Билл Инмон (Bill Inmon)*
**Плюсы**: **Плюсы**:
@@ -295,7 +295,7 @@ fact_sales.order_date BETWEEN dim_customer.valid_from AND dim_customer.valid_to
--- ---
### **2. Звезда (Star Schema)** ### 2. Звезда (Star Schema)
*Источник: Ральф Кимболл (Ralph Kimball)* *Источник: Ральф Кимболл (Ralph Kimball)*
**Плюсы**: **Плюсы**:
@@ -314,7 +314,7 @@ 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). Цель — так организовать хранилище, чтобы можно было спокойно добавлять новые источники и хранить историю, не ломая старую модель.* *Идея: Дэн Линстедт (Dan Linstedt). Цель — так организовать хранилище, чтобы можно было спокойно добавлять новые источники и хранить историю, не ломая старую модель.*
@@ -416,7 +416,8 @@ fact_sales.order_date BETWEEN dim_customer.valid_from AND dim_customer.valid_to
--- ---
### **4. Anchor Modeling (анкерное моделирование)** ### 4. Anchor Modeling (анкерное моделирование)
*Источник: Ларс Рёне (Lars Rönnbäck)* *Источник: Ларс Рёне (Lars Rönnbäck)*
Ещё более атомарный подход: Ещё более атомарный подход:
@@ -439,7 +440,7 @@ fact_sales.order_date BETWEEN dim_customer.valid_from AND dim_customer.valid_to
--- ---
### **Сравнение моделей — наглядно** ### Сравнение моделей — наглядно
```mermaid ```mermaid
quadrantChart quadrantChart
@@ -459,11 +460,11 @@ quadrantChart
--- ---
## **7. Практикум: как собрать первую витрину** ## 7. Практикум: как собрать первую витрину
Покажем на примере `mart_daily_sales` — таблицу, которую можно сразу подключить к BI. Покажем на примере `mart_daily_sales` — таблицу, которую можно сразу подключить к BI.
### **Этапы сборки** ### Этапы сборки
1. Из STG → ODS: 1. Из STG → ODS:
- `stg.orders_raw``ods.orders` (привели `order_date` к `DATE`); - `stg.orders_raw``ods.orders` (привели `order_date` к `DATE`);
@@ -509,9 +510,9 @@ flowchart TD
DM_SALES --> BI DM_SALES --> BI
``` ```
### **Готовые SQL-скрипты** ### Готовые SQL-скрипты
Все необходимые скрипты для построения хранилища находятся в папке [`sql/`](dwh-modeling/sql/): Все необходимые скрипты для построения хранилища находятся в папке [`sql/`](sql/):
- [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql) — создание схем и таблиц (STG, ODS, DDS) - [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql) — создание схем и таблиц (STG, ODS, DDS)
- [`02_dml_stg-dds.sql`](sql/02_dml_stg-dds.sql) — загрузка данных и трансформация - [`02_dml_stg-dds.sql`](sql/02_dml_stg-dds.sql) — загрузка данных и трансформация
@@ -520,7 +521,7 @@ flowchart TD
- [`05_ddl_dm.sql`](sql/05_ddl_dm.sql) — создание витрин (Data Marts) - [`05_ddl_dm.sql`](sql/05_ddl_dm.sql) — создание витрин (Data Marts)
- [`06_dml_dm.sql`](sql/06_dml_dm.sql) — наполнение витрин данными - [`06_dml_dm.sql`](sql/06_dml_dm.sql) — наполнение витрин данными
### **Пример SQL-запроса для витрины** ### Пример SQL-запроса для витрины
```sql ```sql
-- mart_daily_sales: ежедневные продажи с сегментацией -- mart_daily_sales: ежедневные продажи с сегментацией
@@ -547,7 +548,7 @@ GROUP BY d.date_actual, p.product_name, c.customer_segment;
--- ---
## **8. Как выбрать модель данных? Советы от практиков** ## 8. Как выбрать модель данных? Советы от практиков
Выбор модели — **не техническая задача, а стратегическая**. Выбор модели — **не техническая задача, а стратегическая**.
Это как решать: строить дом из кирпича, дерева или SIP-панелей. У каждой технологии — свои плюсы, но **главное — подходит ли она *вам* сегодня**. Это как решать: строить дом из кирпича, дерева или SIP-панелей. У каждой технологии — свои плюсы, но **главное — подходит ли она *вам* сегодня**.
@@ -636,7 +637,7 @@ GROUP BY d.date_actual, p.product_name, c.customer_segment;
--- ---
## **9. Эксплуатация: качество данных — это не «опция»** ## 9. Эксплуатация: качество данных — это не «опция»
Самая красивая архитектура бессмысленна, если в `mart_daily_sales` — нули. Самая красивая архитектура бессмысленна, если в `mart_daily_sales` — нули.
Поэтому в каждом слое — **контроль качества (DQ, Data Quality)**. Поэтому в каждом слое — **контроль качества (DQ, Data Quality)**.
@@ -679,7 +680,7 @@ SELECT 'OK' WHERE EXISTS (
--- ---
## **10. Заключение: главное — понимать «почему»** ## 10. Заключение: главное — понимать «почему»
Хранилище данных — это не про «крутые технологии», а про **мышление**: Хранилище данных — это не про «крутые технологии», а про **мышление**:
@@ -705,7 +706,7 @@ SELECT 'OK' WHERE EXISTS (
--- ---
## **Приложения** ## Приложения
### 📚 Мини-глоссарий (RU / EN) ### 📚 Мини-глоссарий (RU / EN)
@@ -747,11 +748,11 @@ SELECT 'OK' WHERE EXISTS (
--- ---
## **ЧАСТЬ C. Мини-датасет (для практики)** ## ЧАСТЬ C. Мини-датасет (для практики)
Все данные для практики находятся в папке [`data/`](data/) — тренируйтесь: Все данные для практики находятся в папке [`data/`](data/) — тренируйтесь:
[**`customers.csv`**](data/customers.csv): [`customers.csv`](data/customers.csv):
```csv ```csv
customer_id,email,phone,city customer_id,email,phone,city
101,a@ex.com,700,Москва 101,a@ex.com,700,Москва
@@ -759,14 +760,14 @@ customer_id,email,phone,city
102,c@ex.com,701,СПб 102,c@ex.com,701,СПб
``` ```
[**`orders.csv`**](data/orders.csv): [`orders.csv`](data/orders.csv):
```csv ```csv
order_id,order_date,customer_id order_id,order_date,customer_id
5001,2024-01-10,101 5001,2024-01-10,101
5002,2024-02-05,102 5002,2024-02-05,102
``` ```
[**`order_items.csv`**](data/order_items.csv): [`order_items.csv`](data/order_items.csv):
```csv ```csv
order_item_id,order_id,product_id,qty,price_at_sale order_item_id,order_id,product_id,qty,price_at_sale
1,5001,9001,2,100.00 1,5001,9001,2,100.00
@@ -774,14 +775,14 @@ order_item_id,order_id,product_id,qty,price_at_sale
3,5002,9001,1,100.00 3,5002,9001,1,100.00
``` ```
[**`products.csv`**](data/products.csv): [`products.csv`](data/products.csv):
```csv ```csv
product_id,name product_id,name
9001,Phone 9001,Phone
9002,Case 9002,Case
``` ```
[**`prices.csv`**](data/prices.csv): [`prices.csv`](data/prices.csv):
```csv ```csv
product_id,valid_from,valid_to,price product_id,valid_from,valid_to,price
9001,2023-12-01,2024-01-31,100 9001,2023-12-01,2024-01-31,100
@@ -792,7 +793,7 @@ product_id,valid_from,valid_to,price
--- ---
## **ЧАСТЬ D. DDL-скелеты (PostgreSQL)** ## ЧАСТЬ D. DDL-скелеты (PostgreSQL)
Полные DDL-скрипты для всех слоёв хранилища находятся в файле [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql). Полные DDL-скрипты для всех слоёв хранилища находятся в файле [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql).