← Назад к вопросам

Что такое создание витрины?

1.3 Junior🔥 121 комментариев
#Хранилища данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое создание витрины?

Витрина данных (Data Mart) — это подмножество данных хранилища, оптимизированное для конкретного бизнес-процесса или аналитического запроса. Витрина — это специализированная структура данных, ориентированная на определённую область или отдел компании.

Основные характеристики витрины

  • Узкая направленность — данные для конкретной цели (маркетинг, продажи, HR)
  • Оптимизированная структура — таблицы и индексы для быстрых запросов
  • Предрассчитанные агрегаты — средние значения, суммы, формирование на лету
  • Высокий уровень детализации — либо детальные, либо агрегированные данные
  • Быстрый доступ — витрина готовится для быстрых аналитических запросов

Витрина vs Хранилище данных

Хранилище данных (Data Warehouse):

  • Централизованное хранилище для всех данных
  • Универсальное для всех аналитик
  • Полная история, все детали
  • Медленнее для конкретных запросов

Витрина данных (Data Mart):

  • Специализированное подмножество
  • Для конкретного подразделения/задачи
  • Только нужные данные
  • Быстрее для специфических запросов

Типы витрин

1. Витрина по предметной области (Subject-Oriented)

-- Витрина для отдела продаж
CREATE TABLE sales_mart AS
SELECT 
    o.order_id,
    o.order_date,
    c.customer_id,
    c.customer_name,
    c.segment,
    p.product_category,
    p.product_name,
    od.quantity,
    od.price,
    od.quantity * od.price AS total_amount,
    r.region_name,
    r.country
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_details od ON o.order_id = od.order_id
JOIN products p ON od.product_id = p.product_id
JOIN regions r ON c.region_id = r.region_id;

-- Индексы для быстрого доступа
CREATE INDEX idx_sales_date ON sales_mart(order_date);
CREATE INDEX idx_customer ON sales_mart(customer_id);
CREATE INDEX idx_category ON sales_mart(product_category);

2. Витрина с предрассчитанными агрегатами

-- Витрина с месячными показателями
CREATE TABLE sales_monthly_mart AS
SELECT 
    DATE_TRUNC('month', order_date)::DATE AS month,
    customer_id,
    product_category,
    COUNT(DISTINCT order_id) AS order_count,
    SUM(quantity) AS total_quantity,
    SUM(total_amount) AS total_revenue,
    AVG(total_amount) AS avg_order_value,
    MAX(order_date) AS last_order_date
FROM sales_mart
GROUP BY 
    DATE_TRUNC('month', order_date),
    customer_id,
    product_category;

CREATE INDEX idx_month_customer ON sales_monthly_mart(month, customer_id);

3. Витрина «снежинка» (Snowflake Schema)

           FACT TABLE
        (Sales Facts)
              |
      +-------+--------+
      |       |        |
    CUSTOMER PRODUCT   TIME
      |       |        |
      +-+   +-+--------+
        |   |
      LOCATION SUBCATEGORY
-- Таблица фактов
CREATE TABLE sales_fact (
    fact_id SERIAL PRIMARY KEY,
    customer_key INT,
    product_key INT,
    time_key INT,
    quantity INT,
    amount DECIMAL,
    FOREIGN KEY (customer_key) REFERENCES dim_customer(customer_key),
    FOREIGN KEY (product_key) REFERENCES dim_product(product_key),
    FOREIGN KEY (time_key) REFERENCES dim_time(time_key)
);

-- Измерение: Клиент
CREATE TABLE dim_customer (
    customer_key SERIAL PRIMARY KEY,
    customer_id INT,
    customer_name VARCHAR,
    segment VARCHAR,
    location_key INT
);

-- Измерение: Время
CREATE TABLE dim_time (
    time_key SERIAL PRIMARY KEY,
    date DATE,
    month INT,
    quarter INT,
    year INT
);

4. Витрина «звезда» (Star Schema)

         FACT TABLE
       (Sales Facts)
              |
      +-------+-------+-------+
      |       |       |       |
 n   CUSTOMER  PRODUCT TIME  LOCATION

Таблица фактов в центре, измерения вокруг — более простая структура.

Процесс создания витрины (ETL)

import pandas as pd
from sqlalchemy import create_engine, text

# 1. Извлечение данных (Extract)
def extract_from_dwh():
    query = """
    SELECT order_id, customer_id, product_id, order_date, quantity, price
    FROM warehouse.orders
    WHERE order_date >= NOW() - INTERVAL '30 days'
    """
    engine = create_engine('postgresql://user:pass@localhost/warehouse')
    df = pd.read_sql(query, engine)
    return df

# 2. Трансформация (Transform)
def transform_data(df):
    # Очистка
    df = df.dropna()
    
    # Обогащение
    df['revenue'] = df['quantity'] * df['price']
    df['order_date'] = pd.to_datetime(df['order_date'])
    df['month'] = df['order_date'].dt.to_period('M')
    
    # Агрегация
    sales_mart = df.groupby('month').agg({
        'quantity': 'sum',
        'revenue': 'sum',
        'order_id': 'count'
    }).reset_index()
    
    return sales_mart

# 3. Загрузка (Load)
def load_to_mart(df):
    engine = create_engine('postgresql://user:pass@localhost/mart_db')
    df.to_sql('sales_monthly_mart', engine, if_exists='append', index=False)
    print("Витрина успешно обновлена")

# Полный конвейер
if __name__ == "__main__":
    raw_data = extract_from_dwh()
    transformed_data = transform_data(raw_data)
    load_to_mart(transformed_data)

Преимущества витрин

  1. Производительность — оптимизированы для конкретных запросов
  2. Простота — уменьшенное количество таблиц для объединения
  3. Бизнес-ориентированность — структура отражает потребности отдела
  4. Снижение нагрузки — не требуется обращаться к полному хранилищу
  5. Кэширование — часто обновляемые агрегаты готовы к использованию

Недостатки витрин

  1. Дублирование данных — витрины хранят уже существующие данные
  2. Сложность синхронизации — должны обновляться при изменении источника
  3. Жёсткость — переделать витрину сложнее, чем запрос к хранилищу
  4. Затраты на хранение — требуется место для хранения копий

Современные подходы

Lakehouse архитектура (Delta Lake, Apache Iceberg):

# Вместо отдельной витрины, используем слой преобразования
df = spark.read.table("warehouse.orders")

# Создаём "виртуальную витрину" через представление
df.createOrReplaceTempView("sales_mart")

# Или сохраняем как отдельную таблицу с трансформациями
df.groupBy("customer_id", "product_category") \
    .agg({"revenue": "sum"}) \
    .write.mode("overwrite") \
    .option("mergeSchema", "true") \
    .saveAsTable("sales_mart")

Best Practices для витрин

  1. Четко определи назначение — витрина должна решать конкретную задачу
  2. Минимизируй размер — хранить только нужные данные
  3. Автоматизируй обновление — используй scheduler (Airflow, dbt)
  4. Мониторь качество — проверяй целостность и актуальность
  5. Документируй — описывай структуру и логику трансформаций
  6. Версионируй — храни историю изменений витрины

Витрина данных — это мост между сложным хранилищем и потребностями аналитиков, обеспечивая быстрый и удобный доступ к релевантным данным.

Что такое создание витрины? | PrepBro