Files
clickstream-data-platform/docs/labs/1-3-session-overview.md
ddadmin 3bfe9ca4ee docs(labs): уточнены самопроверка и формулировки заданий
Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset.

Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины.

Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся.
2026-09-13 11:20:03 -04:00

116 lines
7.8 KiB
Markdown
Raw Permalink 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.
# Задание 3: `dm.session_overview`
**Чему учит:** хранить слагаемые для расчета средних и долей и понимать,
когда сложение числа посетителей по устройствам завышает аудиторию.
## Сначала прочитать
- [«Хранилище и его слои»](../handbook/storage-layers.md);
- [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md).
## Для чего нужна витрина
Витрина нужна, чтобы по дням сравнивать визиты с телефона и компьютера: их
число, длительность, просмотры страниц и частоту покупок.
Сессии уже рассчитаны в DDS. Из них вы соберете дневные показатели по
устройствам. Почему такие итоги хранят в отдельной таблице, объясняет
[справочник DM](../architecture/dm.md).
## Что сделать
Источник — `dds.session_v`. Зерно — **день сессии × категория устройства**.
Зерно новое, поэтому витрина хранится готовым агрегатом — см. [«Как принято
на ступени 1»](README.md#как-принято-на-ступени-1). Создайте пять объектов:
`dm.session_overview_rep` / `_dist`, донор `_stage_rep` / `_stage_dist` и
публичное представление `dm.session_overview_v`. Ключ партиции — день.
### Состав колонок
| Колонка | Тип | Значение |
|---|---|---|
| `report_date` | `Date` | День сессии |
| `device_category` | `LowCardinality(String)` | Категория устройства |
| `sessions` | `UInt64` | Число визитов |
| `visitors` | `UInt64` | Число разных `client_id` |
| `bounce_sessions` | `UInt64` | Визиты ровно из одного события |
| `purchase_sessions` | `UInt64` | Визиты хотя бы с одной покупкой |
| `duration_seconds_total` | `UInt64` | Суммарная длительность визитов |
| `events_total` | `UInt64` | Число событий во всех визитах |
| `pageviews` | `UInt64` | Число просмотров страниц |
| `cart_adds` | `UInt64` | Число добавлений в корзину |
| `purchases` | `UInt64` | Число покупок |
| `_load_id` | `String` | Идентификатор запуска, собравшего день |
| `_load_ts` | `DateTime64(3, 'UTC')` | Время сборки |
Возьмите `device_category` из сессии: DDS уже заменил код словом. Из четырех
категорий встречаются `desktop`, `mobile` и `tablet`. Строку для `tv`
создавайте только при появлении таких визитов.
Вместо `avg_duration_seconds` храните слагаемые. Среднее из средних по трем
устройствам даст неверный ответ за день: число сессий в категориях
различается, поэтому средние нужно взвешивать. Потребитель делит сумму
`duration_seconds_total` на сумму `sessions`. Долю отказов считают так же:
сумму `bounce_sessions` делят на сумму `sessions`, а не усредняют готовые
доли.
### Ритм пересборки
Сессии прожитого дня больше не меняются. Как в задании 2, определяйте
диапазон от первого несобранного прожитого дня до последнего прожитого.
Соберите его в донор и замените дневные партиции. Добавьте задачу в
`dm_transform`.
### Ключ шардирования
Выберите ключ самостоятельно. Визитов с планшета мало, с телефонов и
компьютеров — значительно больше. Если хотите взять хеш только от
`device_category`, сначала посчитайте строки на каждом шарде. Затем
объясните, почему такое распределение вас устраивает.
Ключ донора — тот же, что у цели (см. [«Как принято на ступени
1»](README.md#как-принято-на-ступени-1) и раздел «Раскладка по шардам»
[справочника хранилища](../architecture/storage.md)).
## Почему сумма `visitors` сходится с `dm.daily_traffic_v`
Сравните сумму `visitors` по устройствам за день с `dm.daily_traffic_v`. На
стенде значения совпадут: устройство приписано куке на всю жизнь, поэтому за
день она учитывается только в одной строке. Это свойство мира стенда; см.
раздел «Паспорт куки» в [словаре понятий](../../CONTEXT.md).
Если появятся визиты одной куки с двух устройств, сумма начнет завышать
аудиторию. Проверки счетчиков по категориям этого не обнаружат. Число
посетителей дня берите из `dm.daily_traffic_v`, где оно рассчитано для дня
целиком.
## Типичная ошибка
Повторное выделение визитов из событий может дать другие границы сессий, чем
в DDS. Используйте готовые сессии из `dds.session_v`. Если общее число
событий совпало с источником, а число сессий завышено, вероятная причина —
сборка витрины из событий вместо сессий.
## Как проверить себя
Деловой ключ — `device_category` внутри дня. Получите прямой агрегат из
`dds.session_v` за день. Соедините его с `dm.session_overview_v` полным
внешним соединением по ключу. Посчитайте строки, где ключ отсутствует с
одной из сторон или различается любой счетчик. Расхождений должно быть ноль.
Еще две проверки дневных итогов:
- сумма `sessions` равна числу строк `dds.session_v` за день — без потерь и
повторного учета визитов;
- сумма `events_total` равна сумме `events_total` по сессиям того же дня.
## Что должно получиться
- [ ] у вас есть пять объектов витрины; донор объявлен через `AS` и
использует ключ шардирования целевой таблицы;
- [ ] вы явно перечислили колонки в `dm.session_overview_v` и собрали
показатели из готовых сессий `dds.session_v`;
- [ ] в таблице хранятся слагаемые для средних и долей;
- [ ] проверка `session_overview` в `homework_check` прошла успешно;
- [ ] витрина обновляется при запуске `dm_transform`.