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

Что такое data lake, data warehouse и data mart? В чём различия?

1.8 Middle🔥 151 комментариев
#Хранилища данных

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

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

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

Data Lake, Data Warehouse и Data Mart

Три основных архитектурных подхода к организации данных, каждый со своими характеристиками и назначением.

Data Lake

Data Lake — это централизованное хранилище большого объёма сырых, неструктурированных и структурированных данных в их исходном формате.

Характеристики:

  • Формат: сырые данные (JSON, CSV, Parquet, изображения, видео)
  • Структура: минимальная, схема-читаемая (schema-on-read)
  • Объём: огромный (тетабайты, петабайты)
  • Обновления: append-only, редко изменяются
  • Примеры: HDFS, S3 AWS, Azure Data Lake Storage
Data Lake структура:
/raw/
  /events/
    /2024-01-01/
      events_raw.json
  /logs/
    application.log
  /images/
    user_profiles/
/processed/
  /analytics/
    events_processed.parquet

Код примера:

# Загрузка в Data Lake (HDFS)
import pyspark.sql.functions as F

df = spark.read.json("/path/to/raw/events/*.json")
df.write.mode("append").parquet("/data_lake/processed/events/")

# Обработка "on-read"
df = spark.read.parquet("/data_lake/processed/events/")
df_cleaned = df.filter(F.col("timestamp").isNotNull())

Data Warehouse

Data Warehouse — это интегрированная база данных, оптимизированная для OLAP запросов с предварительно обработанными, согласованными и структурированными данными.

Характеристики:

  • Формат: структурированные, очищенные данные
  • Структура: звёздная или снежинка (dimensional model)
  • Объём: тератбайты (обычно меньше Data Lake)
  • Обновления: batch обновления (ETL), не real-time
  • Примеры: Snowflake, BigQuery, Redshift, Vertica
Data Warehouse структура:
FACT TABLES (факты):
  - fact_sales (sales_id, date_id, product_id, amount)
  - fact_clicks (click_id, date_id, user_id, page_id)

DIMENSION TABLES (измерения):
  - dim_date (date_id, date, month, year)
  - dim_product (product_id, name, category)
  - dim_customer (customer_id, name, city)

Пример Star Schema:

-- Fact table
CREATE TABLE fact_sales (
    fact_id INT,
    date_id INT,
    product_id INT,
    customer_id INT,
    amount DECIMAL(10, 2),
    quantity INT,
    FOREIGN KEY (date_id) REFERENCES dim_date,
    FOREIGN KEY (product_id) REFERENCES dim_product,
    FOREIGN KEY (customer_id) REFERENCES dim_customer
);

-- Dimension tables
CREATE TABLE dim_date (
    date_id INT PRIMARY KEY,
    date DATE,
    month INT,
    year INT,
    quarter INT,
    day_of_week VARCHAR(10)
);

CREATE TABLE dim_product (
    product_id INT PRIMARY KEY,
    name VARCHAR(100),
    category VARCHAR(50),
    subcategory VARCHAR(50),
    price DECIMAL(10, 2)
);

-- Запрос для аналитики
SELECT 
    d.month,
    d.year,
    p.category,
    SUM(f.amount) as total_sales
FROM fact_sales f
JOIN dim_date d ON f.date_id = d.date_id
JOIN dim_product p ON f.product_id = p.product_id
GROUP BY d.month, d.year, p.category;

Data Mart

Data Mart — это подмножество данных из Data Warehouse, оптимизированное для специфического отдела или функции.

Характеристики:

  • Формат: структурированные, очищенные данные (копия из DW)
  • Объём: меньше Data Warehouse
  • Фокус: узкая область (Sales Mart, Marketing Mart, Finance Mart)
  • Примеры: специализированные БД, витрины данных
Data Warehouse → Data Marts:
        DW
       /|\
      / | \
     /  |  \
 Sales Marketing Finance
  Mart   Mart     Mart

Пример Data Mart для Sales:

-- Sales Mart (витрина для отдела продаж)
CREATE TABLE sales_mart (
    sale_id INT,
    date DATE,
    salesman_name VARCHAR(100),
    customer_name VARCHAR(100),
    product_name VARCHAR(100),
    region VARCHAR(50),
    amount DECIMAL(10, 2),
    commission DECIMAL(10, 2),
    status VARCHAR(20)
);

-- Загруженные из DW данные
INSERT INTO sales_mart
SELECT 
    f.fact_id,
    d.date,
    e.salesman_name,
    c.customer_name,
    p.product_name,
    c.region,
    f.amount,
    f.amount * 0.05 as commission,
    f.status
FROM fact_sales f
JOIN dim_date d ON f.date_id = d.date_id
JOIN dim_employee e ON f.salesman_id = e.employee_id
JOIN dim_customer c ON f.customer_id = c.customer_id
JOIN dim_product p ON f.product_id = p.product_id;

Таблица сравнения

ХарактеристикаData LakeData WarehouseData Mart
Формат данныхСырые, неструктурированныеСтруктурированные, очищенныеСтруктурированные
СхемаSchema-on-readSchema-on-writeПредопределённая
ОбъёмПетабайтыТератбайтыГигабайты-тератбайты
Скорость загрузкиБыстро (raw copy)Медленнее (ETL)Быстро (copy из DW)
ОбновленияAppend-onlyBatch (ночью)Batch (из DW)
ЗапросыAd-hoc, complexАналитические, структурированныеСпециализированные
СтоимостьДешево (простое хранилище)ДорожеЭкономно
ПримерыHDFS, S3, Azure LakeSnowflake, BigQueryВитрины в PostgreSQL

Типовая архитектура (Lambda/Kappa)

Источники данных
    |
    v
Data Lake (raw)
    |
    +---------> Processing Layer
    |              |
    |              v
    |         Data Warehouse (clean, integrated)
    |              |
    |              +---> Sales Mart
    |              |
    |              +---> Marketing Mart
    |              |
    |              +---> Finance Mart
    |
    v
Real-time applications

Практический пример ETL pipeline

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, to_date

spark = SparkSession.builder.appName("ETL").getOrCreate()

# 1. Чтение из Data Lake (сырые данные)
raw_events = spark.read.json("/data_lake/raw/events/*.json")

# 2. Трансформация для Data Warehouse
events_cleaned = raw_events \
    .filter(col("event_id").isNotNull()) \
    .filter(col("timestamp").isNotNull()) \
    .select(
        col("event_id"),
        to_date(col("timestamp")).alias("event_date"),
        col("user_id"),
        col("event_type"),
        col("properties")
    ) \
    .dropDuplicates()

# 3. Загрузка в DW
events_cleaned.write.mode("overwrite").parquet(
    "/data_warehouse/events/"
)

# 4. Создание Data Mart для Marketing
marketing_mart = spark.sql("""
    SELECT 
        event_date,
        user_id,
        COUNT(*) as event_count,
        COUNT(DISTINCT event_type) as unique_events
    FROM events
    WHERE event_type IN ('click', 'view', 'purchase')
    GROUP BY event_date, user_id
""")

marketing_mart.write.mode("overwrite").parquet(
    "/data_mart/marketing/daily_user_activity/"
)

Когда использовать каждый

Выбирай Data Lake если:

  • Нужно хранить все необработанные данные
  • Требуется гибкость в аналитике
  • Есть неструктурированные данные
  • Budget критичен

Выбирай Data Warehouse если:

  • Нужна оптимизация для OLAP запросов
  • Данные мало меняются
  • Требуется высокая производительность аналитики
  • Данные полностью структурированы

Выбирай Data Mart если:

  • Отдел нужны специализированные данные
  • Производительность для конкретных запросов
  • Простота использования для business users

Лучшая практика: использовать все три в комплексе — Data Lake для хранения, Data Warehouse для интеграции и аналитики, Data Marts для специфических потребностей отделов.

Что такое data lake, data warehouse и data mart? В чём различия? | PrepBro