# Учебные задания Программа состоит из двух частей: основная включает семь ступеней, которые вы проходите по порядку, а факультативы выбираете по желанию. Причины такого порядка и формы заданий описаны в [программе учебных лаб](../specs/2026-09-01-labs-program.md#2-устройство-программы-основная-программа-и-факультативы). ## Основная программа | Ступень | Задание | Чему учит | |---|---|---| | 1 | Пять витрин слоя DM | построить результат для потребителя хранилища; уроки каждой витрины — в таблице ниже | | 2 | [Свой график в Superset](2-1-superset-chart.md) | превратить свой результат из хранилища в отчет в BI | | 3 | [Нарежь сессии сам](3-1-sessions-by-hand.md) | сверить число сессий в своей нарезке с эталоном и найти события, из-за которых оно расходится | | 4 | [Перепиши нарезку стенда](4-1-session-pipeline.md) | изменить расчетную сущность внутри готового конвейера и проверить ее внешним эталоном | | 5 | [Сначала сторож, потом ломай: заказы](5-1-order-checks.md)
[Перепишите разбор заказов в ODS](5-2-order-parsing.md)
[Перепишите сборку заказов в DDS](5-3-order-pipeline.md) | написать проверки качества до рискованного изменения, затем переписать разбор и сборку заказов | | 6 | [Разбери сырые события и сверь результат со стендом](6-1-event-parsing.md) | изучить разбор потока отдельно от живого приема и сверить его со стендовым результатом | | 7 | [Мониторинг: куда смотреть](7-1-monitoring.md) | выбрать, куда и на что смотреть в живой системе | ## Ступень 1: пять витрин слоя DM Слой DM в стенде построен наполовину: витрины трех сюжетов дашборда и контроль качества уже построены, остальные пять витрин строите вы. Каждая из них — самостоятельное ТЗ: в нем есть состав витрины, зерно, источники и способ проверки. | № | Результат | Чему учит | |---|---|---| | 1 | [`events_enriched_v`](1-1-events-enriched.md) | строить слой как договор о данных, а не как их копию | | 2 | [`top_pages_daily`](1-2-top-pages-daily.md) | создавать материализованную витрину с дневной пересборкой в конвейере | | 3 | [`session_overview`](1-3-session-overview.md) | хранить слагаемые для расчета средних и долей | | 4 | [`dq_errors_daily`](1-4-dq-errors-daily.md) | считать брак по дню загрузки и хранить итоги дольше источника | | 5 | [`utm_effectiveness`](1-5-utm-effectiveness.md) | читать `declared_` как предупреждение о сумме со слов клиента | Общее устройство слоя — [дока DM](../architecture/dm.md). Она отвечает на вопросы «почему так», задание отвечает на вопрос «что сделать». ## Как принято на ступени 1 **Читать — через `_v`.** Физические `_rep` и `_dist` служат загрузке и обслуживанию, а публичный договор DDS — `dds.event_v` или `dds.session_v` — остается прежним даже при изменении физических объектов. Чтение DDS напрямую делает задания независимыми: соседняя витрина может быть еще не построена. Исключение — задание 4: у таблиц брака публичного договора нет. **Писать — в `_dist`.** Так строки распределяются по ключу шардирования. При записи в локальную таблицу распределение зависит от узла, выполнившего запрос, и при следующем запуске может измениться. Подробности — раздел «Раскладка по шардам» [справочника хранилища](../architecture/storage.md). **Форма — по зерну.** На стенде агрегат с новым зерном принято хранить готовым: потребитель читает его много раз без повторного расчета по источнику. Создайте `dm.<имя>_rep` / `_dist`, донор `dm.<имя>_stage_rep` / `_stage_dist` и публичное `dm.<имя>_v` с явным списком колонок. При прежнем зерне достаточно представления: таблица дублировала бы данные. Доводы — раздел «Форма: по зерну, не по цене запроса» [справочника DM](../architecture/dm.md). **Ключ шардирования — ваше решение.** Объясните, почему выбранный ключ не дает существенного перекоса и почему более сложный ничего не добавит. Объявите донор через `AS <цель>_rep` с ключом цели: иначе замена партиции потеряет строку на одном шарде и удвоит на другом. Детали — раздел «Раскладка по шардам» [справочника хранилища](../architecture/storage.md). Пример обоснования — `dm.revenue_daily_dist` в [`sql/ddl/55-dm-tables.sql`](../../sql/ddl/55-dm-tables.sql). **Где лежит код.** DDL заданий — в `sql/ddl/70-labs.sql`: он применяется после стендовых, поэтому ваши объекты не мешаются со стендовыми. В `sql/dm/<витрина>_scope.sql` определяются дни прогона, в `_rebuild.sql` они собираются в донор, в `_replace.sql` заменяется партиция. Задачу сборки добавьте в [`dags/dm_transform.py`](../../dags/dm_transform.py): без нее конвейер не обновит витрину. Представлению достаточно `CREATE VIEW`. **Образец — витрина `revenue_daily`.** У нее есть пять объектов, донор, сборка, замена дневных партиций и задача в конвейере. Используйте ее как образец всего порядка пересборки. Состав колонок берите из своего ТЗ, иначе получите показатели другой витрины. ## Самопроверка ступени 1 Даг `homework_check` запускается руками, расписания у него нет. Задача витрины красная, пока витрины нет или счет не сходится, и зеленая, когда собрано верно. В сводку качества конвейера `dm.dq_summary` он не пишет: это инструмент лабы, а не история качества стенда. Проверка пяти заданий по витринам устроена одинаково и золотых констант не содержит: рядом с витриной независимым запросом собирается тот же ответ — прямо из источника витрины, минуя ее саму. У четырех заданий источник эталона тот же, что у витрины, `dds.session_v` или `dds.event_v`; у задания 4 это таблицы брака ODS, потому что в DDS нет сущности брака. Обе стороны соединяются по деловому ключу через `FULL OUTER JOIN`, и считается число строк, где стороны разошлись или одной стороны нет. Ноль — зеленый. Полное соединение сохраняет ключи обеих сторон: при внутреннем пропавший день или ключ не попал бы в результат, и потеря осталась бы незамеченной. Раздел «Как проверить себя» каждого ТЗ по витрине называет деловой ключ и сравниваемые величины. Тот же прием в стендовом исполнении — [даг `dq_check`](../../dags/dq_check.py) и запросы в [`sql/dq/`](../../sql/dq). **Предупреждение.** Запросы самой проверки лежат в `sql/dq/` открыто, и имена называют витрину и роль сверки. Проверка на инвариантах неизбежно близка к ответу: чтобы сверить витрину, надо ее пересчитать. Если открыть эти файлы до выполнения задания, можно скопировать готовый SQL, не разобравшись в расчете самостоятельно. Смотреть туда стоит после своей сборки: сравнить два решения полезно, списать одно — нет. ## Факультативы Эти задания вы берете по желанию. Полный список сюжетов — в разделе [«Факультативы — пять разделов»](../specs/2026-09-01-labs-program.md#4-факультативы--пять-разделов) программы. ### Почему выручка не сходится Открывается после ступени 1. Расхождения между источниками, повторы покупок и день, после которого отчет можно считать окончательным. ### Тонкий анализ данных Открывается после ступени 1. Знание о пользователе на дату и обогащение отчета своим словарем. ### Superset и BI Открывается после ступени 2. [Свой дашборд в Superset](superset-dashboard.md): свои объекты BI живут отдельно от стендовых. ### Инженерия стенда Открывается после ступени 1. Прием и хранение данных, раскладка по шардам, повторная обработка дня и обновление витрин. ### Что делать, когда стенд сломался Открывается после ступени 7. Поломки стенда и runbook по итогам расследований; весь раздел — повышенная сложность. ## Уборка Черновики и опыты за собой сносить: правило проверок стенда — [дока тестирования](../architecture/testing.md). Снесенная витрина обязана снова покраснить свою задачу в `homework_check` — если не покраснила, проверка ничего и не проверяла.