Files
ddadmin 4693bc5af9 docs(labs): упрощен язык учебных заданий
- Зачем: начинающим трудно читать задания из-за необъясненных терминов и неестественных формулировок.
- Что: переработаны вводная и 21 задание, названы темы разделов, объяснены термины и сокращены повторы; согласованы правила учебного текста и ссылки.
- Проверка: сохранены 25 блоков SQL и команд и таблицы состава колонок; проверены 153 локальные ссылки и 32 входящие ссылки на разделы; git diff --check прошел.
2026-10-18 18:09:43 +02:00

206 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Учебные задания
Вы будете достраивать хранилище небольшого интернет-магазина. Стенд уже
загружает события сайта и заказы, обрабатывает их и строит несколько отчетов.
Сначала вы подготовите данные для новых отчетов, затем разберетесь, как
работают расчеты и загрузка, и перепишете часть из них.
Основная программа состоит из семи ступеней. Проходите их по порядку,
факультативы выбирайте по желанию. Перед первым заданием прочитайте главу
[«Хранилище и его слои»](../handbook/storage-layers.md) и выполните запросы
из нее: они покажут данные, с которыми предстоит работать.
## Порядок заданий
| Ступень | Задания | Содержание |
|---|---|---|
| 1 | Пять витрин для отчетов | подготовить данные о событиях, страницах, визитах, ошибках загрузки и рекламе; задания перечислены ниже |
| 2 | [Свой график в Superset](2-1-superset-chart.md) | построить график по своей витрине и проверить числа на нем |
| 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) | сохранить итоги в таблице и настроить их обновление через Airflow |
| 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) | различать суммы покупок из событий сайта и выручку по заказам магазина |
Начните с [первого задания](1-1-events-enriched.md): для него достаточно
одного представления. В заданиях 2–5 понадобятся таблицы и их обновление
по дням. К общим правилам ниже возвращайтесь по мере работы.
## Создание и обновление витрин
### Источники данных
События читайте из `dds.event_v`, сессии из `dds.session_v`. Суффикс `_v`
обозначает обычное представление: оно выполняет сохраненный запрос при
чтении. Такие представления сохраняют привычные имена и состав колонок,
когда внутреннее устройство таблиц меняется.
Каждая учебная витрина читает готовый источник и не зависит от других
учебных витрин. В задании 4 источниками служат таблицы ошибок ODS:
представлений для них нет.
### Таблицы и представления
В заданиях 2–5 вы группируете исходные строки. Например, в `top_pages_daily`
одна строка содержит итоги для одной страницы за день. То, чему соответствует
одна строка, называют **зерном**. На стенде итоги с новым зерном сохраняют
в таблицах. Отчеты читают готовые числа.
Новый расчет сначала записывают в промежуточную таблицу. Пока он готовится,
отчеты читают прежние данные из основной. Затем готовыми разделами
промежуточной таблицы заменяют разделы основной. Раздел называется
**партицией**; в этих заданиях он содержит данные одного дня.
Промежуточную таблицу также называют **донором**.
На примере `top_pages_daily` пять объектов выглядят так:
| Объект | Для чего нужен |
|---|---|
| `dm.top_pages_daily_rep` | Хранит рассчитанные строки на каждом шарде |
| `dm.top_pages_daily_dist` | Читает строки со всех шардов и распределяет запись между ними |
| `dm.top_pages_daily_stage_rep` | Хранит новый расчет до замены данных в основной таблице |
| `dm.top_pages_daily_stage_dist` | Распределяет запись нового расчета между шардами |
| `dm.top_pages_daily_v` | Дает отчетам доступ к готовой витрине; явно перечисляет ее колонки |
### Распределение по шардам
Каждый из двух шардов стенда хранит свою часть данных. Записывайте строки
через таблицы `_dist`: они выбирают шард по ключу шардирования. Прямая запись
в `_rep` оставит строки на том узле, где выполнен запрос.
Ключ для своей витрины выберите сами. Проверьте распределение строк между
шардами и объясните, почему выбранного ключа достаточно.
Пример обоснования для `dm.revenue_daily_dist` есть в
[`sql/ddl/55-dm-tables.sql`](../../sql/ddl/55-dm-tables.sql).
Создайте промежуточную таблицу через `AS <цель>_rep`, сохранив структуру и
ключи основной. У обеих таблиц `_dist` должен быть одинаковый ключ
шардирования: замена партиции выполняется внутри каждого шарда и не
перераспределяет строки. Подробности есть в разделе
[«Раскладка по шардам»](../architecture/storage.md#раскладка-по-шардам).
### SQL-файлы и запуск расчета
Команды создания таблиц и представлений (DDL) сохраняйте в
`sql/ddl/70-labs.sql`. При создании мира этот файл выполняется после
стендовых файлов. В работающем стенде примените команды сами по инструкции
ниже: сохранение файла и повторный `make up` их не выполнят.
Для витрины с таблицами нужны три файла в `sql/dm/`:
- `<витрина>_scope.sql` определяет, какие дни пересчитать;
- `<витрина>_rebuild.sql` рассчитывает их и записывает в промежуточную таблицу;
- `<витрина>_replace.sql` заменяет партицию одного дня в основной таблице.
Добавьте запуск расчета в [`dags/dm_transform.py`](../../dags/dm_transform.py),
чтобы витрина обновлялась вместе с остальными. Для представления из задания 1
достаточно выполнить `CREATE VIEW`.
Образец этого порядка работы есть у готовой витрины `revenue_daily`.
Ее таблицы, SQL-файлы и задача Airflow разобраны в
[справочнике DM](../architecture/dm.md#dmrevenue_daily_v).
Состав колонок и выбор дней для пересчета берите из своего задания.
## Выполнение SQL в DBeaver
В 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).
Сохраненный файл позволит воссоздать ваши объекты при пересборке мира.
## Проверка витрин
В Airflow есть даг `homework_check` с отдельной задачей для каждой учебной
витрины. Запускайте его вручную: расписания у него нет. Задача завершится
ошибкой, если витрина еще не создана или ее данные расходятся с ожидаемыми.
Причину и примеры расхождений ищите в журнале задачи. Проверки еще не
выполненных заданий тоже будут красными.
Проверка заново рассчитывает показатели по источнику и сравнивает их с вашей
витриной. Строки сопоставляются по полям, которые их определяют: например,
по дню и странице. `FULL OUTER JOIN` позволяет найти и разные значения, и
строки, которых нет с одной стороны. `INNER JOIN` пропустил бы отсутствующие
строки. Когда расхождений нет, задача становится зеленой.
`homework_check` не сохраняет результаты в сводку качества `dm.dq_summary`.
Запросы проверок лежат в [`sql/dq/`](../../sql/dq/). Откройте их после собственного решения:
они заново рассчитывают показатели витрины, поэтому содержат ответ на
существенную часть задания. Сравните свой способ расчета с готовым.
## Задания по желанию
Полный список сюжетов — в разделе
[«Факультативы — пять разделов»](../specs/2026-09-01-labs-program.md#4-факультативы--пять-разделов)
программы.
### Почему выручка не сходится
Открывается после ступени 1. Четыре расследования качества данных:
- [Куда пропали покупки](optional/missing-purchases.md): найти заказы без
события, выбрать источник витрины и условие проверки полноты.
- [Почему повтор покупки завышает выручку](optional/duplicate-purchases.md):
рассчитать выручку с одной строкой на заказ и проверить результат на
повторных событиях.
- [Какая позиция объясняет разницу в сумме](optional/order-amount-difference.md):
разобрать товары заказа без потери точности и найти причину разницы в суммах.
- [Почему вчерашняя выручка меняется сегодня](optional/revenue-over-time.md):
определить, за какие дни пересчитывать выручку и какую историю заказов сохранять.
Первые три работы используют готовые данные. Четвертая продвигает мир через
Airflow; для нее вы сохраняете состояния заказов после каждого модельного дня.
### Данные о посетителях
Открывается после ступени 1.
- [Как новые заказы меняют отчет о посетителях](optional/identity-over-time.md):
сохранить историю связей, сравнить расчеты на прежних сессиях и определить,
какие сведения нужны для воспроизведения результата.
### Отчеты в Superset
Открывается после ступени 2. Два самостоятельных задания:
- [Свой дашборд в Superset](optional/superset-dashboard.md): собрать отчет
из своих витрин и подтвердить выводы запросами.
- [В DBeaver работает, в Superset нет](optional/superset-missing-object.md):
выяснить, почему клиенты по-разному видят один объект хранилища.
### Загрузка и обновление данных
Открывается после ступени 1.
- [Как обновлять витрину без полной пересборки](optional/incremental-daily-traffic.md):
продолжить работу о связях пользователей, пересчитать затронутые дни
и проверить повтор незавершенной загрузки. Повышенная сложность.
## Удаление временных объектов
После опытов удаляйте свои временные объекты. Если удалили учебную витрину,
ее задача в `homework_check` должна снова завершиться ошибкой: отсутствие
витрины тоже проверяется. Подробнее — в
[справочнике проверок](../architecture/testing.md).