- Зачем:
- README и путеводитель обращаются к читателю на «вы», а ТЗ в docs/labs/
были на «ты»; после пересборки индекса смесь стала заметна.
- Что:
- во всех восьми файлах docs/labs/ местоимения, глаголы и повелительное
наклонение переведены во второе лицо множественного числа.
- названия ступеней в таблице README оставлены как в спеке.
- Проверка:
- grep по формам «ты/твой», 'ё' и 'менти' по docs/labs/ молчит;
git diff --check чистый; ревью диффа свежей сессией.
7.7 KiB
Задание 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нет — и не должно быть.