Files
clickstream-data-platform/docs/labs/events-enriched.md
T
ddadmin 3556566f64 docs(labs): обращение «вы» во всех учебных заданиях
- Зачем:
  - README и путеводитель обращаются к читателю на «вы», а ТЗ в docs/labs/
    были на «ты»; после пересборки индекса смесь стала заметна.
- Что:
  - во всех восьми файлах docs/labs/ местоимения, глаголы и повелительное
    наклонение переведены во второе лицо множественного числа.
  - названия ступеней в таблице README оставлены как в спеке.
- Проверка:
  - grep по формам «ты/твой», 'ё' и 'менти' по docs/labs/ молчит;
    git diff --check чистый; ревью диффа свежей сессией.
2026-09-03 17:28:51 -04:00

7.7 KiB
Raw Blame History

Задание 1: dm.events_enriched_v

Чему учит: слой — это контракт, а не копия данных. Витрина, которая не меняет зерно источника, остается представлением, и копии событий ради других имен колонок не заводит ни один боевой склад.

Это разминка. Строк она не хранит, в конвейер не встает, ключа шардирования у нее нет. Задача одна: собрать плоское событие для BI и не поддаться соблазну разложить его на диск.

Роль витрины

Договор события в DDS широкий — 44 колонки, почти весь формат выгрузки: часть из них технические координаты источника, часть — параллельные массивы товаров. Аналитику в Superset нужен плоский набор деловых полей и пара производных, которые иначе каждый пишет заново в каждом запросе.

Витрина отвечает на вопрос «что вообще происходило»: с нее начинают, когда надо посмотреть на события глазами человека, а не разбирать широкую строку источника.

Источником для витрин следующих заданий она не служит. Витрина слоя DM читает публичный договор DDS — так устроены и стендовые витрины, и потому задания независимы: соседнюю домашку можно делать первой, а можно не делать вовсе.

Зерно и форма

Зерно — событие: одна строка витрины равна одной строке dds.event_v. Зерно источника сохранено, значит форма — обычное представление CREATE VIEW dm.events_enriched_v, без физической таблицы, без донора и без задачи в dm_transform. Пересобирать нечего.

Источник — dds.event_v, и только он.

Состав колонок

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

Время и посетитель: event_date, event_time, event_hour, client_id, event_id.

Действие: event_type (pageview, add_to_cart, purchase), url, page_path, referer, referer_host, title.

Атрибуция: utm_source, utm_medium, utm_campaign, utm_content, utm_term.

Паспорт визита: device_category, browser, operating_system, region_country, region_city.

Торговый блок, массивами как в источнике: product_id, product_name, product_category, product_price, product_quantity, product_event_type, purchase_id, purchase_revenue, purchase_coupon.

Три колонки в источнике не лежат и считаются здесь:

Колонка Как считается Зачем
event_hour toHour(event_time) суточный профиль спрашивают в каждом отчете
page_path путь url без домена и параметров группировка по странице без разбора строки в каждом запросе
referer_host домен referer «откуда пришли» одним значением, а не полным адресом

Служебных _load_id и _load_ts у витрины нет, и это не забывчивость. Их нет и у dds.event_v: событие в DDS не грузят, а читают из ODS, поэтому координат собственной загрузки у него не бывает. Служебная колонка называет запуск, который положил строку на диск, — здесь на диск никто ничего не кладет.

Ловушка задания

Массивы product_* тянет развернуть через ARRAY JOIN — так плоская таблица становится по-настоящему плоской. Разворачивать нельзя, и вреда здесь два.

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

Неочевидный и куда более разрушительный: ARRAY JOIN — соединение внутреннее, и строку с пустым массивом он выбрасывает. Торговый блок пуст у всех событий, кроме корзин и покупок, то есть у подавляющего большинства. Так «плоская таблица событий» превращается в таблицу товарных позиций и теряет девятнадцать строк из двадцати — а по имени и по составу колонок она по-прежнему выглядит таблицей событий. Ошибка не падает и ничего не подсвечивает.

Массивы едут в договор как есть; разворачивает их тот, кому нужна позиция заказа, — и делает это уже в своей витрине, с другим зерном и другим именем.

Как проверить себя

Деловой ключ — event_id внутри дня. Соберите прямой ответ из dds.event_v за тот же день, соедините с витриной полным внешним соединением и посчитайте строки, где ключа нет с одной из сторон или где различаются значения деловых колонок. Ноль — зеленый.

Отдельно проверяются три производные колонки: event_hour, page_path и referer_host должны совпасть с тем же выражением, посчитанным по dds.event_v на лету.

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

Приемка

  • dm.events_enriched_v создано, физических таблиц под ним нет;
  • список колонок в представлении явный;
  • число строк и набор event_id совпадают с dds.event_v за каждый прожитый день;
  • задача events_enriched в homework_check зеленая;
  • задачи в dm_transform нет — и не должно быть.