docs(labs): упрощен язык учебных заданий
Зачем: помочь менти понять действия, проверить результат и оценить освоенное умение. Что: вычитаны 13 заданий основной программы и общий индекс. Итоговые списки обращены к учащемуся, убраны история разработки и повторы. Правила учебного текста записаны в программе, из AGENTS.md добавлена ссылка. Проверка: git diff --check, локальные ссылки и ссылки на измененные заголовки прошли. Блоки кода и таблицы требований совпадают с исходными. Упражнения на стенде повторно не выполнялись: изменен только текст.
This commit is contained in:
1 parent
a03838b953
commit
4058e18864
16 files changed
+287
-269
No files matched your search
@@ -15,7 +15,7 @@
|
||||
Готовый стендовый разбор находится в `sql/ddl/30-ods-views.sql`. Откройте его
|
||||
после собственной сверки: в нем лежит ответ на основную часть задания.
|
||||
|
||||
## Граница задания
|
||||
## Что предстоит сделать
|
||||
|
||||
Создайте в базе `default` одну свою таблицу годных событий и наполните ее одним
|
||||
пакетным `INSERT SELECT` из `stg.hits_raw_dist`. Работайте с первой нодой под
|
||||
@@ -72,11 +72,10 @@ Airflow. При включенном `world_live` посмотрите его т
|
||||
`ods.event_rep`, а также `_load_ts`. Тип `purchaseRevenue` возьмите из ODS:
|
||||
`Array(Decimal(18, 2))`.
|
||||
|
||||
Схлопните повтор доставки по договору ODS. Возьмите
|
||||
Обработайте повторные доставки так же, как ODS. Возьмите
|
||||
`ReplacingMergeTree(_load_ts)`, партицию `EventDate` и полный ключ замены:
|
||||
`(CounterID, EventDate, intHash32(ClientID), WatchID)`. Достаточно одной
|
||||
локальной таблицы: отдельная Distributed-таблица не добавит урока к пакетному
|
||||
опыту на одной ноде.
|
||||
локальной таблицы: загрузка и сверка в этом опыте выполняются на одной ноде.
|
||||
|
||||
`WatchID` — логический идентификатор события, уникальный по
|
||||
[договору генератора](../specs/2026-08-01-generator.md). Физический ключ ODS
|
||||
@@ -85,8 +84,7 @@ Airflow. При включенном `world_live` посмотрите его т
|
||||
|
||||
## Разберите годные строки
|
||||
|
||||
Для каждой строки среза примите решение по тому же строгому входу, что и
|
||||
стенд:
|
||||
Для каждой строки среза проверьте те же условия приема, что и на стенде:
|
||||
|
||||
1. корень `raw` — JSON-объект;
|
||||
2. набор верхнеуровневых ключей в точности равен 47 ключам формата;
|
||||
@@ -95,25 +93,25 @@ Airflow. При включенном `world_live` посмотрите его т
|
||||
|
||||
Напишите разбор, который не прерывает пакет из-за одной грязной строки. Сами
|
||||
выберите способ безопасного извлечения пяти опорных полей, форму общих выражений
|
||||
и место фильтра. Остальные поля извлеките по договору формата.
|
||||
и место фильтра. Остальные поля извлеките по описанию формата.
|
||||
|
||||
Перенесите `_load_ts` из STG без пересчета: это время исходной доставки и
|
||||
колонка версии. Время запуска вашего запроса сюда не входит. Вставьте в свою
|
||||
таблицу только годные строки выбранного среза.
|
||||
|
||||
Считайте отвергнутые строки прямо в исходном срезе: отдельная таблица брака в
|
||||
задание не входит. Проверьте работу строгого входа одним запросом. Посчитайте:
|
||||
Считайте отвергнутые строки прямо в исходном срезе, без отдельной таблицы
|
||||
брака. Одним запросом посчитайте:
|
||||
|
||||
- все доставки;
|
||||
- строки, прошедшие ваш предикат;
|
||||
- строки, отвергнутые его отрицанием.
|
||||
- строки, прошедшие ваше условие отбора;
|
||||
- строки, для которых это условие ложно.
|
||||
|
||||
Проверьте равенство общего числа строк сумме прошедших и отвергнутых. Так каждая
|
||||
исходная строка учитывается ровно в одной группе. Если отвергнутые строки есть,
|
||||
сохраните их `raw`, `_load_ts` и координаты Kafka. Найдите те же
|
||||
координаты в `ods.event_errors_dist` и запишите стендовый `error_class`. Если
|
||||
брака нет, так и зафиксируйте: опыт проверил успешную ветвь и выполнение
|
||||
предиката на этом срезе, но не классификатор ошибок. Подкладывать грязные
|
||||
условия отбора на этом срезе, но не классификатор ошибок. Подкладывать грязные
|
||||
сообщения ради задания не требуется.
|
||||
|
||||
## Приведите стороны к одному зерну
|
||||
@@ -126,17 +124,17 @@ Airflow. При включенном `world_live` посмотрите его т
|
||||
полных ключей среди годных доставок. Разница между числом доставок и этим
|
||||
счетом показывает повторы в исходном срезе.
|
||||
|
||||
Область эталона постройте независимо от своего предиката и результата вставки.
|
||||
Снова возьмите весь исходный STG-срез. По координатам Kafka исключите доставки,
|
||||
которые есть в `ods.event_errors_dist`. У оставшихся доставок извлеките
|
||||
`WatchID` без риска прервать запрос и выберите эти события из свежего
|
||||
Выберите строки ODS для сравнения независимо от своего условия отбора и
|
||||
результата вставки. Снова возьмите весь исходный STG-срез. По координатам Kafka
|
||||
исключите доставки, которые есть в `ods.event_errors_dist`. У оставшихся
|
||||
доставок извлеките `WatchID` без риска прервать запрос и выберите эти события из свежего
|
||||
`ods.event_v`.
|
||||
|
||||
Свяжите сырую доставку с ODS по `WatchID`: по договору генератора это уникальный
|
||||
идентификатор события. Он задает только область эталона. Дедупликация и
|
||||
последующее соединение используют полный физический ключ. Не берите область из
|
||||
своей таблицы и не применяйте к ней свой предикат. Иначе ошибочно отвергнутая
|
||||
строка исчезнет с обеих сторон сверки.
|
||||
идентификатор события. Здесь он нужен только для выбора событий ODS.
|
||||
Удаление повторов и последующее соединение используют полный физический ключ.
|
||||
Не берите список событий из своей таблицы и не применяйте к нему свое условие
|
||||
отбора. Иначе ошибочно отвергнутая строка исчезнет с обеих сторон сверки.
|
||||
|
||||
## Сверьте 47 полей
|
||||
|
||||
@@ -171,44 +169,46 @@ ClickHouse по умолчанию заполняет отсутствующую
|
||||
|
||||
Для измененной строки назовите поля, которые расходятся, и сравните каждое с
|
||||
сырой строкой. Для пропавшей или лишней строки проверьте пять опорных полей и
|
||||
решение строгого предиката. Если координаты доставки есть в
|
||||
результат условия отбора. Если координаты доставки есть в
|
||||
`ods.event_errors_dist`, посмотрите `error_class`.
|
||||
|
||||
Исправьте разбор, удалите и заново создайте только собственную таблицу, затем
|
||||
повторите вставку того же среза. Остановитесь, когда счет исходных доставок по
|
||||
прежним границам не изменился, баланс строгого входа сошелся, а построчная
|
||||
сверка пуста.
|
||||
прежним границам не изменился, число годных и отвергнутых строк в сумме дает
|
||||
число исходных доставок, а построчная сверка пуста.
|
||||
|
||||
## Где заканчивается проверка
|
||||
## Чего не подтверждает сравнение с ODS
|
||||
|
||||
`ods.event_v` — образец для сравнения. Оба разбора могли повторить одну
|
||||
ошибку. Для пяти опорных полей у вас есть проверка разбираемости и исходный
|
||||
JSON. Остальные 42 поля можно вручную сопоставить с `raw`, однако второго
|
||||
независимого источника для всех значений на стенде нет.
|
||||
ошибку. Для пяти опорных полей у вас есть проверка преобразования в нужный тип
|
||||
и исходный JSON. Остальные 42 поля можно вручную сопоставить с `raw`, однако
|
||||
второго независимого источника для всех значений на стенде нет.
|
||||
|
||||
## Уберите свой объект
|
||||
|
||||
Сохраните DDL таблицы, запрос разбора, границы среза, баланс строгого входа и
|
||||
пустую итоговую сверку. Затем удалите свою таблицу командой `DROP TABLE` с ее
|
||||
точным именем. Убедитесь через `system.tables`, что объекта больше нет.
|
||||
Сохраните DDL таблицы, запрос разбора, границы среза, число исходных, годных
|
||||
и отвергнутых строк и итоговую сверку без расхождений. Запишите также, чего
|
||||
не подтверждает сравнение с ODS и как TTL ограничивает время для повторения
|
||||
опыта. Затем удалите свою таблицу командой `DROP TABLE` с ее точным именем.
|
||||
Убедитесь через `system.tables`, что объекта больше нет.
|
||||
Прикладные строки стенда вы не меняли, поэтому удалять данные из STG, ODS или
|
||||
Kafka после опыта не нужно.
|
||||
|
||||
## Приемка
|
||||
## Что должно получиться
|
||||
|
||||
- [ ] записаны границы малого завершенного среза, его счет и координаты
|
||||
- [ ] у вас сохранены границы выбранного среза, число строк и координаты
|
||||
доставки по партициям Kafka;
|
||||
- [ ] создана одна собственная таблица со всеми 47 полями, перенесенным
|
||||
`_load_ts` и физическим договором дедупликации ODS;
|
||||
- [ ] пакетный разбор принимает только JSON-объекты с точным набором ключей и
|
||||
пятью разбираемыми опорными полями;
|
||||
- [ ] счет исходных строк равен сумме годных и отвергнутых, а найденный брак
|
||||
рассмотрен по `raw`, координатам и стендовому классу;
|
||||
- [ ] область ODS получена из всех координат исходного среза и стендовой
|
||||
таблицы ошибок, независимо от собственного предиката и таблицы;
|
||||
- [ ] обе стороны приведены к зерну полного физического ключа;
|
||||
- [ ] `FULL OUTER JOIN` сравнивает все 47 полей, а числа пропавших, лишних и
|
||||
измененных строк равны нулю;
|
||||
- [ ] отдельно подтвержден перенос `_load_ts` и учтены повторы доставки;
|
||||
- [ ] границы стендового оракула и TTL записаны вместе с результатом;
|
||||
- [ ] собственная таблица удалена, объекты и данные стенда не изменены.
|
||||
- [ ] вы собрали свою таблицу со всеми 47 полями и `_load_ts`, используя
|
||||
те же правила удаления повторов, что и ODS;
|
||||
- [ ] ваш разбор принимает только JSON-объекты с точным набором ключей и
|
||||
пятью опорными полями, которые преобразуются в нужные типы;
|
||||
- [ ] вы сверили число исходных строк с суммой годных и отвергнутых,
|
||||
а найденный брак разобрали по `raw`, координатам и классу ошибки стенда;
|
||||
- [ ] вы выбрали события ODS по исходному срезу и таблице ошибок,
|
||||
независимо от своей таблицы и условия отбора;
|
||||
- [ ] вы сравнили обе стороны по полному физическому ключу через
|
||||
`FULL OUTER JOIN`: во всех 47 полях нет расхождений,
|
||||
пропавших и лишних строк тоже нет;
|
||||
- [ ] вы отдельно проверили перенос `_load_ts` и учли повторные доставки;
|
||||
- [ ] вы записали ограничения сравнения с ODS и срок повторения опыта;
|
||||
- [ ] после опыта вы удалили свою таблицу, сохранив объекты и данные стенда.
|
||||
Reference in new issue
Block a user