Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset. Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины. Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся.
160 lines
13 KiB
Markdown
160 lines
13 KiB
Markdown
# Учебные задания
|
||
|
||
Программа состоит из двух частей: основная включает семь ступеней, которые вы
|
||
проходите по порядку, а факультативы выбираете по желанию. Причины такого
|
||
порядка и формы заданий описаны в [программе учебных лаб](../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)<br>[Перепишите разбор заказов в ODS](5-2-order-parsing.md)<br>[Перепишите сборку заказов в 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`.
|
||
При создании мира он применяется после стендовых файлов.
|
||
В уже работающем стенде сохранение файла и повторный `make up` новый DDL
|
||
не применят — выполните его сами, как описано ниже. В
|
||
`sql/dm/<витрина>_scope.sql` определяются дни прогона, в `_rebuild.sql` они
|
||
собираются в донор, в `_replace.sql` заменяется партиция. Задачу сборки
|
||
добавьте в [`dags/dm_transform.py`](../../dags/dm_transform.py): без нее
|
||
конвейер не обновит витрину. Представлению достаточно `CREATE VIEW`.
|
||
|
||
**Образец — витрина `revenue_daily`.** У нее есть пять объектов, донор,
|
||
сборка, замена дневных партиций и задача в конвейере. Используйте ее как
|
||
образец всего порядка пересборки. Состав колонок берите из своего ТЗ, иначе
|
||
получите показатели другой витрины.
|
||
|
||
## Как применить свой DDL
|
||
|
||
В DBeaver создайте подключение по [инструкции в README](../../README.md#подключиться-из-dbeaver),
|
||
но укажите пользователя `etl` и пароль из `CLICKHOUSE_ETL_PASSWORD` в `.env`.
|
||
Пользователь `analyst` из той инструкции предназначен для чтения;
|
||
у `etl` есть права создавать таблицы и представления в `dm`.
|
||
|
||
Создайте файл `sql/ddl/70-labs.sql` и сохраняйте в нем DDL своих витрин.
|
||
Откройте его в SQL-редакторе этого подключения и выполните DDL текущего
|
||
задания. Создавайте объекты с
|
||
`ON CLUSTER clickstream_cluster`, чтобы они появились на обеих нодах;
|
||
образец для представления — [`sql/ddl/60-dm-views.sql`](../../sql/ddl/60-dm-views.sql).
|
||
Сохраненный файл позволит воссоздать ваши объекты при пересборке мира.
|
||
|
||
## Самопроверка ступени 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/`. Откройте их после собственного решения:
|
||
они заново рассчитывают показатели витрины, поэтому содержат ответ на
|
||
существенную часть задания. Сравните свой способ расчета с готовым.
|
||
|
||
## Факультативы
|
||
|
||
Эти задания вы берете по желанию. Полный список сюжетов — в разделе
|
||
[«Факультативы — пять разделов»](../specs/2026-09-01-labs-program.md#4-факультативы--пять-разделов)
|
||
программы.
|
||
|
||
### Почему выручка не сходится
|
||
|
||
Открывается после ступени 1. Расхождения между источниками, повторы
|
||
покупок и день, после которого отчет можно считать окончательным.
|
||
|
||
### Тонкий анализ данных
|
||
|
||
Открывается после ступени 1. Знание о пользователе на дату и обогащение
|
||
отчета своим словарем.
|
||
|
||
### Superset и BI
|
||
|
||
Открывается после ступени 2. Два самостоятельных задания:
|
||
|
||
- [Свой дашборд в Superset](optional/superset-dashboard.md): собрать отчет
|
||
из своих витрин и подтвердить выводы запросами.
|
||
- [В DBeaver работает, в Superset нет](optional/superset-missing-object.md):
|
||
выяснить, почему клиенты по-разному видят один объект хранилища.
|
||
|
||
### Инженерия стенда
|
||
|
||
Открывается после ступени 1. Прием и хранение данных, раскладка по шардам,
|
||
повторная обработка дня и обновление витрин.
|
||
|
||
### Что делать, когда стенд сломался
|
||
|
||
Открывается после ступени 7. Поломки стенда и инструкции по восстановлению
|
||
по итогам расследований; весь раздел — повышенная сложность.
|
||
|
||
## Уборка
|
||
|
||
После опытов удаляйте свои временные объекты. Если удалили учебную витрину,
|
||
ее задача в `homework_check` должна снова завершиться ошибкой: отсутствие
|
||
витрины тоже проверяется. Подробнее — в
|
||
[справочнике проверок](../architecture/testing.md).
|