Files
clickstream-data-platform/docs/handbook/storage-layers.md
T
ddadminandClaude Fable 5.1 e07484e9c2 docs(handbook): раздел DDS главы о хранилище дополнен сессией и примером
- Зачем:
  - ТЗ ступени 3 отправляет в главу за определением визита и доводом, почему
    стенд считает сессии сам; раздел давал о сессии одно предложение.
- Что:
  - в разделе «DDS: язык бизнеса» описаны договоренность о визите, роль
    Метрики и эталон VisitID, session_id и чтение через dds.session_v.
  - в «Посмотрите сами» добавлен запрос сессий дня между примерами ODS и DM,
    итоговая фраза переписана на три запроса.
- Проверка:
  - make lint; запрос к dds.session_v выполнен на стенде под analyst.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 10:59:35 -04:00

167 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Хранилище и его слои
В хранилище приходят два потока из Kafka: в топике `hits` — события
кликстрима, в `orders` — заказы магазина. Оба проходят один путь: STG → ODS →
DDS → DM. Каждый слой отвечает на свой вопрос.
```mermaid
flowchart LR
Kafka --> STG --> ODS --> DDS --> DM
```
## Как читать имена
Для обычного чтения выбирайте объекты с суффиксом `_v`. Это представления:
их устройство может поменяться, а ваш запрос останется прежним. Суффиксы
`_rep`, `_dist`, `_kafka` и `_mv` относятся к внутреннему
устройству хранилища. Они нужны для загрузки, обслуживания и диагностики.
У словарей есть исключение: у `dic.products` нет суффикса, потому что
различать нечего — объект один.
Подробный разбор имен есть в [справочнике
хранилища](../architecture/storage.md#имена-объектов).
## STG: как поступило
STG — сырой слой. Он сохраняет сообщение целой строкой, без разбора. Рядом
лежат метаданные доставки: топик, партиция, смещение и время приема. Поэтому в
STG можно увидеть, что именно приехало из Kafka, даже если сообщение
испорчено.
Срок хранения — трое суток реального времени. Этого хватает для расследования
и повторного разбора, но старые строки не занимают диск вечно. Точное правило
— в [справочнике
хранилища](../architecture/storage.md#срок-жизни-сырых-данных).
## ODS: язык источника
ODS — слой разобранных данных. Строка получает типы: дата становится датой,
число — числом. Имена полей остаются на языке источника. Например, событие
сохраняет колонки `WatchID`, `ClientID` и `EventDate`.
Испорченное сообщение не останавливает загрузку. Оно попадает в таблицу
`*_errors` вместе с сырой строкой и классом ошибки. Так брак остается виден, а
годные строки продолжают движение.
## DDS: язык бизнеса
DDS — детальный слой на языке бизнеса. Здесь есть событие, заказ, сессия и
карта идентичностей. Карта связывает посетителя, то есть куку `ClientID`, с
пользователем магазина из заказа.
В стенде визитом считают подряд идущие события одной куки без пауз
дольше 30 минут. Визит не пересекает границу модельных суток.
Аналитик называет такой визит сессией.
В бою Метрика нарезает визиты сама и добавляет готовый `VisitID` в
события. Стенд играет ее роль: считает сессии из событий заново, а `VisitID`
оставляет эталоном для проверки. Иначе сборка сессий свелась бы к группировке
по чужому полю, и учиться было бы не на чем. Идентификатор сессии
`session_id` чеканит стенд: в событии его нет. Готовые сессии читайте через
`dds.session_v`. В `dds.event_v` поля `VisitID` нет: так сессии можно собрать
самому и сравнить с эталоном.
## DM: данные для дашбордов
DM — слой витрин. Витрина — готовый набор показателей для отчета или
дашборда. Здесь уже посчитаны, например, дневная выручка по категориям и
дневные показатели трафика.
К каждой витрине можно обращаться коротким запросом, не повторяя в нем весь
путь расчета. Состав готовых витрин смотрите в [карте
таблиц](../architecture/storage.md#карта-таблиц).
## Сбоку цепочки: зона `dic`
Зона `dic` стоит вне пути STG → ODS → DDS → DM. В ней живут справочные данные,
которые хранилище получает готовыми. Ни один слой их не производит, а читать
может любой.
Первый справочник стенда — каталог товаров `dic.products`. Его ключ `sku` —
артикул товара. По нему можно узнать название, бренд и категорию товара. Как
устроена зона, смотрите в [разделе о
справочниках](../architecture/storage.md#справочники).
## Сквозные ключи
Один и тот же смысл проходит через слои под разными именами: имя меняется
вместе с языком слоя. Таблица показывает исходное имя и то, где искать тот же
смысл дальше.
| Колонка | Что означает | Что соединяет |
|---|---|---|
| `WatchID` | Идентификатор события | Событие ODS с событием DDS, где колонка называется `event_id` |
| `ClientID` | Посетитель, то есть кука | События ODS с событиями, сессиями и картой идентичностей DDS; в DDS колонка называется `client_id` |
| `order_id` | Идентификатор заказа | Заказ ODS с заказом DDS и витриной сверки `dm.purchase_vs_orders_v` |
| `sku` | Артикул товара в каталоге | Справочник `dic.products` с позициями заказа DDS, где артикулы лежат в `item_sku`; через категорию товара — с витриной выручки DM |
| `EventDate` | День на [оси модельного времени](../../CONTEXT.md), который счетчик сайта проставляет в [своем часовом поясе](../architecture/storage.md#часовые-пояса) | Событие ODS с событием DDS, где колонка называется `event_date`, и дневными расчетами DM |
Что здесь значит «посетитель» и чем кука отличается от человека, объясняет
[словарь понятий](../../CONTEXT.md#язык). Точные имена объектов и полей сверяйте с
[картой таблиц](../architecture/storage.md#карта-таблиц).
## Посмотрите сами
Подключитесь к ClickHouse по инструкции из разделов [«Адреса и
пароли»](../../README.md#адреса-и-пароли) и [«Подключиться из
DBeaver»](../../README.md#подключиться-из-dbeaver). Во всех трех примерах
`2026-06-01` — это D0, первый день [стартового
мира](../../CONTEXT.md). Чтобы посмотреть другой день, замените
эту дату в условии. Первый запрос покажет
события одного модельного дня:
```sql
SELECT
WatchID,
ClientID,
EventDate,
EventType,
URL
FROM ods.event_v
WHERE EventDate = '2026-06-01'
ORDER BY UTCEventTime
LIMIT 20;
```
Второй запрос покажет сессии того же дня. Они рассчитаны из событий
первого запроса:
```sql
SELECT
client_id,
started_at,
finished_at,
events_total,
pageviews,
purchases,
entry_url
FROM dds.session_v
WHERE session_date = '2026-06-01'
ORDER BY events_total DESC
LIMIT 20;
```
Третий запрос покажет готовую выручку по категориям за тот же день:
```sql
SELECT
product_category,
orders,
units,
revenue
FROM dm.revenue_daily_v
WHERE report_date = '2026-06-01'
ORDER BY revenue DESC;
```
Все три запроса читают поверхности `_v`. Первый показывает данные на языке
источника, второй — расчетную сущность, третий — готовый ответ витрины.
## Куда дальше
Откройте [интерактивную карту](architecture-map.html) из своей копии
репозитория и проследите путь данных.
Список объектов, сроки хранения и устройство таблиц — в [справочнике
хранилища](../architecture/storage.md). Как данные переносят между слоями — в
следующей главе: [потоки Airflow и даги модельного
времени](airflow-dags.md).