# Задание 3: `dm.session_overview` **Чему учит:** хранить слагаемые, а не готовые средние и доли. Понимать, почему сумма `visitors` по строкам сейчас сходится, но начнет завышать аудиторию, если у одной куки появятся визиты с двух устройств. ## Сначала прочитать - [«Хранилище и его слои»](../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`.