Все материалы
Продуктовая аналитикаматериалстарт

DWH, витрина данных и data lake: что это и чем они отличаются

DWH — хранилище данных для анализа, витрина — готовая таблица под конкретную задачу, data lake — хранилище сырых файлов. Чем DWH отличается от базы приложения, из каких слоёв состоит, как выглядит витрина на SQL и почему в двух витринах бывают разные цифры.

КейсПрактика24 сентября 2026 г.10 мин

На совещании два дашборда показывают выручку за август. В одном 15 788 долларов, в другом 12 595. Оба «из хранилища», оба построены аналитиками, и оба посчитаны правильно — просто это разные метрики с одинаковой подписью. Чтобы разобраться, откуда такое берётся, нужно понимать, как устроено место, где живут аналитические данные. DWH (data warehouse, хранилище данных) — это отдельная база, куда данные из разных систем компании собирают, очищают и хранят с историей, чтобы их можно было анализировать. Витрина данных — готовая таблица внутри хранилища, собранная под конкретную задачу или команду. Data lake (озеро данных) — хранилище сырых файлов любого формата, которые складывают как есть и разбирают при чтении.

Коротко

  • DWH — аналитическая база, в которой собраны данные из приложения, биллинга, CRM и других источников в согласованном виде и с историей.
  • Витрина данных — таблица под конкретный вопрос: дневные метрики продукта, выручка по каналам, воронка онбординга.
  • Data lake хранит сырые файлы дёшево и в любом формате, но структуру приходится разбирать при каждом чтении.
  • Хранилище обычно делят на слои: сырые данные, очищенный детальный слой и витрины.
  • Разные цифры в двух витринах чаще всего означают разные определения метрики, а не ошибку в SQL.

Что такое DWH (хранилище данных) простыми словами

Хранилище данных — это база, созданная не для работы продукта, а для ответов на вопросы о нём. Приложение пишет события и заказы в свою базу, биллинг — оплаты в свою, CRM — сделки в свою. В хранилище эти данные приезжают по расписанию через ETL-процесс, приводятся к единым типам и ключам и лежат рядом, поэтому их можно соединять в одном запросе.

Второе свойство DWH — история. База приложения хранит текущее состояние: тариф пользователя сейчас. Хранилище может хранить, каким тариф был в каждый момент, и поэтому отвечает на вопросы вроде «сколько было платящих на конец июля».

Учебная база SQL-курса — маленькая модель такого хранилища. В ней пять таблиц и 45 185 строк: пользователи, события приложения, оплаты, подписки и попадания в эксперименты. В реальной компании эти данные пришли бы из трёх-четырёх разных систем.

Чем хранилище отличается от базы приложения

База приложения рассчитана на много коротких операций: записать событие, найти пользователя по id, списать деньги. Такие системы называют OLTP. Хранилище рассчитано на тяжёлые запросы по миллионам строк: посчитать DAU за квартал, сравнить когорты. Это OLAP-нагрузка. Подробно разница разобрана в материале про OLAP и OLTP, ссылка в конце.

Главная практическая причина не считать аналитику прямо в базе приложения — она мешает продукту. Тяжёлый запрос аналитика может замедлить приложение для пользователей. Вторая причина — в базе приложения нет данных других систем, и выручку по каналам привлечения там просто не с чем соединить.

Что сравниваемБаза приложения (OLTP)Хранилище (DWH)
Зачемчтобы продукт работалчтобы отвечать на вопросы о продукте и бизнесе
Типичный запроснайти одну строку, записать одну строкуагрегировать миллионы строк за период
Источникиодна системамного систем, сведённых по ключам
Историяв основном текущее состояниеистория изменений и снимки
Кто пишетприложениеконвейеры загрузки (ETL/ELT)

Из каких слоёв состоит хранилище

Названия слоёв в компаниях разные, но логика почти всегда одна: данные проходят путь от сырых к готовым, и на каждом шаге их становится меньше, а смысла больше.

Сырой слой (raw, staging) хранит данные так, как их отдал источник, иногда с минимальной чисткой. К нему почти не ходят с аналитическими запросами, но он нужен, чтобы пересчитать всё заново, если в логике найдут ошибку.

Детальный слой (core, detail, иногда ODS или DDS) — очищенные таблицы на уровне отдельных фактов: одно событие, одна оплата, один пользователь. Здесь уже нет дублей, типы согласованы, ключи связывают таблицы. Таблицы users, events и payments учебной базы похожи именно на этот слой.

Слой витрин (marts) — агрегаты и широкие таблицы под конкретные задачи. Дашборды и отчёты читают в основном отсюда.

Слои хранилища на примере продукта
СлойЧто лежитПримерКто читает
Сырой (raw, staging)данные как пришли из источникаJSON событий из приложения, выгрузка оплат из биллингадата-инженеры
Детальный (core, detail)очищенные факты и справочникиevents, payments, usersаналитики, для новых вопросов
Витрины (marts)агрегаты и таблицы под задачудневные метрики продукта, выручка по каналамдашборды, менеджеры, аналитики

Что такое витрина данных

Витрина данных (data mart) — таблица, собранная под конкретный вопрос или команду, чтобы его не приходилось каждый раз собирать с нуля. Если продакт каждое утро смотрит DAU, регистрации и выручку по дням, логично один раз свести их в таблицу «одна строка — один день» и строить дашборд на ней.

Ниже такая витрина, собранная одним запросом на учебной базе. Каждый CTE считает показатель из своего источника: активность — из событий, регистрации — из пользователей, выручку и новых плательщиков — из оплат. Затем всё соединяется по дню. В хранилище результат сохраняли бы как таблицу и обновляли после каждой загрузки.

Последняя неделя витрины (учебная база, DuckDB). Выручка в долларах
daydausignupsnew_payersrevenue
2026-08-244848513529
2026-08-255298616660
2026-08-265688713519
2026-08-275568714604
2026-08-285868812646
2026-08-295303811607
2026-08-30223020721
Дневная витрина продукта: DAU, регистрации, новые плательщики, выручка
with days as (
  select distinct event_time::date as day from events
),
activity as (
  select event_time::date as day, count(distinct user_id) as dau
  from events
  group by 1
),
signups as (
  select signup_date as day, count(*) as signups
  from users
  group by 1
),
revenue as (
  select
    paid_at as day,
    sum(amount) as revenue,
    count(*) filter (where payment_type = 'first') as new_payers
  from payments
  group by 1
)
select
  d.day,
  a.dau,
  coalesce(s.signups, 0) as signups,
  coalesce(r.new_payers, 0) as new_payers,
  coalesce(r.revenue, 0) as revenue
from days as d
left join activity as a on a.day = d.day
left join signups as s on s.day = d.day
left join revenue as r on r.day = d.day
where d.day between date '2026-08-24' and date '2026-08-30'
order by d.day;

Почему последняя строка витрины врёт

Посмотрите на 30 августа: DAU упал до 223, регистраций ноль, а выручка максимальная за неделю. Продукт тут ни при чём. Выгрузку закрыли в 13:00, поэтому события есть только за первую половину дня. В таблице пользователей регистрации заканчиваются 29 августа, и витрина честно ставит ноль. Оплаты хранятся с точностью до даты, и по ним не видно, полный ли день.

Витрина свела в одну строку три источника с разной свежестью. Каждая цифра в ней правильная для своей таблицы, а вместе они рассказывают несуществующую историю. Хорошая витрина хранит рядом с данными отметку, до какого момента она полна, а дашборд не показывает дни после этой отметки или помечает их как неполные.

Ноль и «нет данных» — разные вещи

coalesce(s.signups, 0) удобен для графиков, но превращает «регистрации не загружены» в «регистраций не было». Если источник мог не доехать, оставляйте NULL и проверяйте свежесть каждого источника перед обновлением витрины.

Факты и измерения: схема «звезда»

Детальный слой часто строят по схеме «звезда». В центре — таблицы фактов: каждая строка фиксирует событие или операцию с числами, которые можно суммировать. Вокруг — таблицы измерений: справочники, по которым факты режут.

В учебной базе events (35 341 строка) и payments (1251 строка) — факты. users (4613 строк) — измерение: у каждого пользователя есть канал привлечения, страна и устройство. Запрос «выручка по каналам» — типичный запрос к звезде: взять факт, присоединить измерение, сгруппировать по его атрибуту.

channelpaymentsrevenue
organic2837087
referral1984792
partner902200
paid_search711709
Факт оплат, разрезанный по измерению «канал»: август 2026
select
  u.channel,
  count(*) as payments,
  sum(p.amount) as revenue
from payments as p
join users as u on u.user_id = p.user_id
where p.paid_at between date '2026-08-01' and date '2026-08-31'
group by u.channel
order by revenue desc;

Data lake, DWH и lakehouse: в чём разница

Data lake — хранилище файлов: логи, JSON событий, выгрузки, картинки, файлы в колоночных форматах. Файлы складывают как есть, а структуру описывают в момент чтения (schema on read). Это дёшево и гибко: можно сохранить данные, даже если пока непонятно, как их использовать. Обратная сторона — без дисциплины озеро превращается в свалку файлов, которые никто не может найти и прочитать.

DWH хранит таблицы с заранее описанной структурой (schema on write): данные проверяют и приводят к схеме при загрузке. Писать в него сложнее, зато читать просто, и аналитики работают с ним на SQL.

Lakehouse — подход, в котором поверх файлов озера добавляют табличный слой: схему, транзакции, версии данных. Так к файлам можно обращаться почти как к таблицам хранилища. Это не отдельный продукт, а архитектурный выбор, и многие компании живут без него.

Что сравниваемData lakeDWHLakehouse
Что хранитфайлы любого формататаблицыфайлы с табличным слоем поверх
Когда описана структурапри чтениипри загрузкепри записи в таблицы поверх файлов
Кто в основном работаетдата-инженеры, ML-командыаналитики, BIи те, и другие
Сильная сторонадёшево хранить всё, в том числе сырьёсогласованные данные, быстрый SQLодна копия данных для аналитики и ML
Типичная проблемасложно найти и доверять даннымдорого менять структурусложнее в настройке и сопровождении

Кто за что отвечает: дата-инженер и аналитик

Дата-инженер отвечает за то, чтобы данные доезжали: конвейеры загрузки, сырой и детальный слои, расписание, мониторинг, права доступа. Если данные за вчера не пришли, это его зона.

Аналитик отвечает за смысл: какие витрины нужны, как определены метрики, правильно ли их читают. Он первым замечает, что цифра странная, и должен уметь отличить поломку данных от изменения в продукте.

Между ними часто появляется роль analytics engineer: человек, который пишет SQL-модели детального слоя и витрин, покрывает их тестами и документирует определения. В небольших командах всё это делает один аналитик, и тогда особенно важно, чтобы логика витрин лежала в коде, а не в головах.

Почему в двух витринах разные цифры

Вернёмся к двум «выручкам» из начала. Первая витрина суммирует оплаты, прошедшие в августе: 15 788 долларов. Вторая суммирует месячную цену всех активных подписок: 12 595 долларов. Первая показывает деньги, которые пришли за месяц. Вторая ближе к MRR — регулярному доходу, который приносят подписки на текущий момент. Обе цифры верны, но подпись «выручка» на обеих вводит в заблуждение.

С активностью то же самое. 28 августа хотя бы одно событие сделали 586 пользователей. Если считать активными только тех, кто сделал ключевое действие, то есть что-то кроме открытия приложения, их 91. Витрина маркетинга и витрина продукта могут называть DAU разные вещи, и никто этого не заметит, пока цифры не положат рядом.

Две «выручки» из одной базы
select
  (select sum(amount)
   from payments
   where paid_at between date '2026-08-01' and date '2026-08-31') as payments_august,
  (select sum(monthly_price)
   from subscriptions
   where status = 'active') as active_subscriptions_monthly;
  • Держите определение каждой метрики в одном месте: одна модель или витрина, из которой читают все дашборды.
  • Называйте колонки по смыслу: payments_august и active_subscriptions_monthly, а не две колонки revenue.
  • У каждой витрины должен быть владелец, который отвечает на вопрос «как это посчитано».
  • Храните отметку полноты данных и не показывайте незакрытый день как обычный.

Что читать дальше

Как данные попадают в хранилище, разобрано в материале про ETL. Почему одна и та же метрика даёт разные ответы, — в разборе ошибок чтения метрик.

Продолжить чтение
Вся библиотека
Продуктовая аналитика24 сентября 2026 г.10 мин
Три потока разноцветных частиц сходятся в воронку и выходят ровными рядами

ETL: что это простыми словами, этапы и чем ETL отличается от ELT

ETL — процесс, который забирает данные из источников, приводит их в порядок и загружает в хранилище. Этапы extract, transform, load на примере продукта, разница ETL и ELT, инкрементальная загрузка, идемпотентность и SQL-проверки качества данных.

Читать материал
Продуктовая аналитика24 сентября 2026 г.10 мин
Горизонтальные полосы-строки слева и вертикальные столбцы справа, между ними поток точек

OLAP и OLTP: в чём разница простыми словами

OLTP — системы, которые обслуживают работу продукта мелкими транзакциями, OLAP — системы для тяжёлых аналитических запросов. Чем они отличаются по запросам, схеме и хранению, почему отчёты не строят на рабочей базе и что такое OLAP-куб.

Читать материал
Продуктовая аналитика24 сентября 2026 г.11 мин
Ровные повторяющиеся столбики, над которыми тянется одна длинная полоса

MRR и ARR: что это, как считать и что они скрывают

MRR — регулярная выручка активных подписок, приведённая к одному месяцу, ARR — та же величина в годовом масштабе. Как посчитать MRR в SQL, что делать с просроченными оплатами, чем MRR отличается от денег за месяц и из чего складывается его изменение.

Читать материал