docs(labs): упрощен язык учебных заданий
- Зачем: начинающим трудно читать задания из-за необъясненных терминов и неестественных формулировок. - Что: переработаны вводная и 21 задание, названы темы разделов, объяснены термины и сокращены повторы; согласованы правила учебного текста и ссылки. - Проверка: сохранены 25 блоков SQL и команд и таблицы состава колонок; проверены 153 локальные ссылки и 32 входящие ссылки на разделы; git diff --check прошел.
This commit is contained in:
1 parent
3c3eb825e1
commit
4693bc5af9
24 files changed
+782
-684
No files matched your search
@@ -1,19 +1,20 @@
|
||||
# Почему повтор покупки завышает выручку
|
||||
|
||||
**Чему учит:** выбрать зерно и ключ расчета, чтобы повторные события
|
||||
не умножали денежную сумму.
|
||||
Несколько событий покупки могут относиться к одному заказу. Вы проверите,
|
||||
как они завышают сумму, и составите расчет, который учитывает каждый заказ
|
||||
один раз.
|
||||
|
||||
Факультатив доступен после ступени 1. Работайте в DBeaver пользователем
|
||||
`analyst` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; оставьте `world_live` на паузе и
|
||||
дождитесь уже начатых прогонов, чтобы данные не менялись между запросами.
|
||||
|
||||
## Проверьте расчет по событиям
|
||||
## Расчет по событиям покупки
|
||||
|
||||
В ODS уже устранены повторные доставки событий. Достаточно ли этого,
|
||||
чтобы сложить суммы всех `purchase` для витрины заказов? Проверьте на данных.
|
||||
|
||||
Возьмите один закрытый день: его дата должна быть не позднее
|
||||
Возьмите день, за который уже получены все слепки заказов: его дата должна быть не позднее
|
||||
`max(snapshot_date) - 6` из `ods.order_v`. Во всех запросах к `dds.event_v`
|
||||
отбирайте этот `event_date` и `event_type = 'purchase'`.
|
||||
|
||||
@@ -22,12 +23,12 @@
|
||||
|
||||
Сначала посчитайте число событий и сумму всех заявленных сумм. Затем найдите
|
||||
номера заказов, которые встречаются несколько раз. Если таких нет, выберите
|
||||
другой закрытый день.
|
||||
другой день с полученными слепками.
|
||||
|
||||
Для двух повторившихся покупок выпишите `event_id`, `client_id`, `event_time`,
|
||||
номер заказа и сумму. Сопоставьте число событий и заказов в `dds.order_v`.
|
||||
|
||||
## Соберите расчет по заказам
|
||||
## Расчет по заказам
|
||||
|
||||
Напишите запрос с одной строкой на номер заказа. Сохраните в результате
|
||||
номер, число исходных событий и одну заявленную сумму. До выбора суммы
|
||||
@@ -38,7 +39,7 @@
|
||||
разных номеров в исходных событиях. Отдельно проверьте свое решение на случае
|
||||
двух разных заказов с одинаковой суммой: сколько денег оно учтет?
|
||||
|
||||
## Найдите заказы, из-за которых сумма завышена
|
||||
## Заказы с повторными событиями
|
||||
|
||||
Возьмите один повторившийся номер заказа. Сколько денег он добавил в первый
|
||||
расчет и сколько — во второй? Подтвердите разность его событиями.
|
||||
@@ -58,22 +59,23 @@
|
||||
его статус и [порядок присвоения классов](../../architecture/dm.md#dmpurchase_vs_orders_v).
|
||||
Класс витрины не заменяет поиск всех повторов в событиях.
|
||||
|
||||
## Определите границы расчета
|
||||
## Сравнение с выручкой магазина
|
||||
|
||||
Сложите `revenue` из `dm.revenue_daily_v` за тот же `report_date` по всем
|
||||
категориям. Эта витрина считает стоимость позиций оплаченных заказов,
|
||||
без скидки и доставки.
|
||||
|
||||
Сравните результат с исправленной клиентской суммой. Совпадение не требуется:
|
||||
Сравните результат с суммой по событиям после устранения повторов. Совпадение не требуется:
|
||||
удаление повторов устраняет одну причину расхождения. Найдите хотя бы один
|
||||
заказ, который объясняет, почему деньги трекера и магазина все еще могут
|
||||
различаться. Для этого сопоставьте события, заказ и готовую сверку.
|
||||
|
||||
Рядом со своим запросом укажите его зерно и ключ. Обоснуйте, где нужна одна
|
||||
строка на событие, а где — одна на заказ: следует ли ради этого расчета
|
||||
Рядом с запросом укажите, чему соответствует одна строка результата
|
||||
и какие поля ее определяют. Обоснуйте, где нужна одна строка на событие,
|
||||
а где одна на заказ: следует ли ради этого расчета
|
||||
удалять повторные покупки из `dds.event_v`? Используйте найденные `event_id`.
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] сохранен запрос с одной строкой на заказ, числом событий и суммой;
|
||||
- [ ] уникальность ключа и полнота набора номеров проверены по источнику;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Как новые заказы меняют отчет о посетителях
|
||||
|
||||
**Чему учит:** сохранять историю связей посетителей с покупателями
|
||||
и использовать ее для воспроизведения прежнего расчета.
|
||||
Вы сохраните историю связей посетителей сайта с покупателями магазина.
|
||||
На ее основе проверите, как новые связи меняют старые отчеты и что нужно,
|
||||
чтобы повторить прежний расчет.
|
||||
|
||||
Факультатив доступен после ступени 1. Понадобятся Airflow и DBeaver с
|
||||
подключением `student` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
@@ -9,13 +10,14 @@
|
||||
ваши таблицы будут доступны только на узле этого подключения.
|
||||
Если предложенное имя таблицы занято, выберите свое.
|
||||
|
||||
В событиях сайта посетитель обозначен кукой `client_id`, а в заказах
|
||||
покупатель — `user_id`. Сопоставив событие покупки с заказом, можно связать
|
||||
эти идентификаторы. Тогда и к прежним визитам этой куки можно добавить
|
||||
В событиях сайта посетитель обозначен `client_id` из cookie браузера,
|
||||
а в заказах покупатель обозначен `user_id`. Сопоставив событие покупки
|
||||
с заказом, можно связать эти идентификаторы. Тогда и к прежним визитам
|
||||
этого `client_id` можно добавить
|
||||
пользователя магазина. Вы проверите, как появление такой связи меняет число
|
||||
известных пользователей в отчете за прошедший день.
|
||||
|
||||
## Сопоставьте посетителей с покупателями
|
||||
## Связи посетителей с покупателями
|
||||
|
||||
Поставьте `world_live` на паузу, дождитесь завершения начатых прогонов
|
||||
генерации и обработки. Запустите `etl_pipeline` и дождитесь успеха.
|
||||
@@ -32,7 +34,8 @@
|
||||
найдите самое раннее время события покупки, которое удалось сопоставить
|
||||
с заказом. Назовите эту колонку `first_purchase_at`.
|
||||
В событии `purchase` массив `purchase_id` содержит один номер заказа.
|
||||
Статус заказа не ограничивайте: отмена покупки не меняет владельца куки.
|
||||
Статус заказа не ограничивайте: отмена покупки не меняет найденную связь
|
||||
посетителя с покупателем.
|
||||
|
||||
Источники распределены по разным ключам. Для соединения используйте
|
||||
`GLOBAL INNER JOIN`, заключив выборки событий и заказов в подзапросы.
|
||||
@@ -43,7 +46,7 @@
|
||||
Для одной пары покажите номера заказов и события, по которым получили
|
||||
`first_purchase_at`.
|
||||
|
||||
## Сохраните список связей после каждого модельного дня
|
||||
## История связей
|
||||
|
||||
Создайте таблицу:
|
||||
|
||||
@@ -84,7 +87,7 @@ SELECT max(event_date) AS observation_day FROM dds.event_v;
|
||||
не устраняет повторы вставки. Сохраните и проверьте список перед тем,
|
||||
как запускать следующий модельный день.
|
||||
|
||||
## Сравните дату покупки с датой появления связи
|
||||
## Дата покупки и дата появления связи
|
||||
|
||||
Сравните списки за соседние даты: H0 с H1, затем H1 с H2. Найдите пары,
|
||||
которых не было в прежнем списке. Для нескольких таких пар покажите
|
||||
@@ -101,7 +104,7 @@ SELECT max(event_date) AS observation_day FROM dds.event_v;
|
||||
у вас нет более ранних копий списка. Для новой пары можно установить
|
||||
интервал между двумя сохранениями, но не точное время внутри него.
|
||||
|
||||
## Пересчитайте отчет за прежние дни
|
||||
## Пересчет прежних отчетов
|
||||
|
||||
Возьмите один и тот же набор сессий из `dds.session_v` за даты до H0
|
||||
включительно. Постройте два дневных расчета:
|
||||
@@ -128,7 +131,7 @@ SELECT max(event_date) AS observation_day FROM dds.event_v;
|
||||
На примере найденных различий объясните, какие данные нужно сохранять,
|
||||
чтобы повторить прежний расчет.
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
У вас есть запрос сопоставления посетителей с покупателями, три сохраненных
|
||||
списка связей и сравнение двух расчетов на одном наборе сессий. На конкретных
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Как обновлять витрину без полной пересборки
|
||||
|
||||
**Чему учит:** выбирать дни для пересчета по новым данным, проверять результат
|
||||
и повторять незавершенную загрузку.
|
||||
Вы настроите обновление витрины только за дни, затронутые новыми данными.
|
||||
Затем проверите, можно ли продолжить загрузку, которая успела записать
|
||||
лишь часть результатов.
|
||||
|
||||
Факультатив повышенной сложности продолжает работу
|
||||
[«Как новые заказы меняют отчет о посетителях»](identity-over-time.md).
|
||||
@@ -18,7 +19,7 @@
|
||||
Удаление данных, исправления старых сессий и пересоздание мира потребовали бы
|
||||
другого способа обнаружения изменений.
|
||||
|
||||
## Создайте витрину и журнал успешных загрузок
|
||||
## Витрина и журнал загрузок
|
||||
|
||||
Создайте две локальные таблицы. Если имена заняты, выберите свои.
|
||||
|
||||
@@ -52,7 +53,7 @@ ORDER BY observation_day;
|
||||
и успешной сверки. Максимальная дата в журнале укажет, какой список
|
||||
использовался в последней завершенной загрузке.
|
||||
|
||||
## Выполните первую загрузку целиком
|
||||
## Первая загрузка
|
||||
|
||||
Убедитесь, что `world_live` стоит на паузе и нет активных прогонов генерации
|
||||
и обработки. Запустите `etl_pipeline` и дождитесь успеха. Получите текущую
|
||||
@@ -79,7 +80,7 @@ ORDER BY observation_day;
|
||||
и различия обоих показателей. Учебную витрину читайте с `FINAL`.
|
||||
После совпадения запишите дату наблюдения в журнал один раз.
|
||||
|
||||
## Найдите дни, которые нужно пересчитать
|
||||
## Выбор дней для пересчета
|
||||
|
||||
Продвиньте мир на один день: `world_next_day` с `days = 1`, затем
|
||||
`etl_pipeline`; после каждого запуска дождитесь успеха. Сохраните новый
|
||||
@@ -90,7 +91,7 @@ ORDER BY observation_day;
|
||||
даты для пересчета без повторов. Он должен учесть два изменения:
|
||||
|
||||
- в сессиях появились дни, которых еще нет в вашей витрине;
|
||||
- в списке на H появились пары, которых не было в списке на P; у этих кук
|
||||
- в списке на H появились пары, которых не было в списке на P; у этих `client_id`
|
||||
есть сессии, в том числе за прежние дни.
|
||||
|
||||
Сначала выведите даты и выберите один прежний день: какая новая пара
|
||||
@@ -103,7 +104,7 @@ ORDER BY observation_day;
|
||||
найденными сравнением списков? Покажите пару, которую ограничение по дате
|
||||
покупки пропускает.
|
||||
|
||||
## Обновите выбранные дни
|
||||
## Обновление витрины
|
||||
|
||||
Напишите второй `INSERT INTO ... SELECT`. Для выбранных дат он должен
|
||||
рассчитать все сессии с полным списком связей на H. Прибавление числа новых
|
||||
@@ -117,7 +118,7 @@ ORDER BY observation_day;
|
||||
Запрос должен вернуть пустой результат, а витрина — остаться прежней.
|
||||
Повторно записывать H в журнал не требуется.
|
||||
|
||||
## Проверьте повторный запуск после частичной загрузки
|
||||
## Повтор незавершенной загрузки
|
||||
|
||||
Снова запустите `world_next_day` с `days = 1`, затем `etl_pipeline`,
|
||||
дожидаясь успеха каждого. Сохраните новый список связей с его датой H.
|
||||
@@ -133,7 +134,7 @@ ORDER BY observation_day;
|
||||
не означает, что витрина обновлена. Что изменится, если записать H в журнал
|
||||
до обновления витрины?
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
Сохраните SQL первой загрузки, выбора дат, обновления и сверки.
|
||||
После двух новых модельных дней ваша витрина совпадает со стендовой,
|
||||
@@ -143,8 +144,9 @@ ORDER BY observation_day;
|
||||
Сравните число пересчитанных дней с полной загрузкой и перечислите,
|
||||
какие дополнительные данные пришлось хранить. Так можно оценить объем работы.
|
||||
На небольшом стенде полный пересчет может быть дешевле.
|
||||
В вашей реализации поиск связей пока читает всю историю покупок —
|
||||
инкрементальным стал именно пересчет дневной витрины.
|
||||
В вашей реализации поиск связей пока читает всю историю покупок.
|
||||
По новым данным обновляется только дневная витрина; такое обновление
|
||||
называют инкрементальным.
|
||||
|
||||
После работы удалите свои `lab_daily_traffic`, `lab_traffic_runs` и
|
||||
`lab_identity_history` через `DROP TABLE`, если они больше не нужны.
|
||||
@@ -1,21 +1,24 @@
|
||||
# Куда пропали покупки
|
||||
|
||||
**Чему учит:** проверить полноту данных по независимому источнику и выбрать
|
||||
источник для витрины заказов.
|
||||
Вы сравните покупки из событий сайта с заказами магазина. Найденные
|
||||
расхождения помогут выбрать источник для полной витрины заказов.
|
||||
|
||||
Факультатив доступен после ступени 1. В DBeaver подключитесь пользователем
|
||||
`analyst` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; на время расследования оставьте
|
||||
`world_live` на паузе и дождитесь уже начатых прогонов.
|
||||
|
||||
## Выберите день
|
||||
## Выбор дня
|
||||
|
||||
Можно ли построить полную витрину заказов по событиям `purchase`?
|
||||
Проверьте это на одном дне: сначала сопоставьте события сайта, затем сверьте
|
||||
номера заказов с выгрузкой магазина.
|
||||
|
||||
Возьмите день, для которого уже получен последний слепок семидневного окна.
|
||||
Запрос показывает самую позднюю подходящую дату:
|
||||
Слепок заказов содержит их состояние на конец модельного дня. Состояние
|
||||
заказа может меняться семь дней, поэтому для окончательного сравнения нужны
|
||||
все слепки за этот период. Возьмите день, для которого уже получен последний
|
||||
из них. Такой день называется закрытым. Запрос показывает самую позднюю
|
||||
подходящую дату:
|
||||
|
||||
```sql
|
||||
SELECT max(snapshot_date) - 6 AS last_closed_day
|
||||
@@ -27,7 +30,7 @@ FROM ods.order_v;
|
||||
Сравнивайте все заказы дня, включая отмененные: сейчас вопрос в том,
|
||||
зарегистрировал ли магазин заказ, а не в том, был ли он оплачен.
|
||||
|
||||
## Найдите разрыв в событиях
|
||||
## События оформления заказа
|
||||
|
||||
При оформлении заказа посетитель видит страницу подтверждения, а трекер
|
||||
отправляет событие покупки. Просмотр страницы и покупка — отдельные события.
|
||||
@@ -42,7 +45,7 @@ FROM ods.order_v;
|
||||
заказа пришло ровно по одному событию каждого вида? Что можно предположить
|
||||
по вашему результату и чего эти два числа еще не доказывают?
|
||||
|
||||
## Сверьте с магазином
|
||||
## Сверка с заказами магазина
|
||||
|
||||
В событии номер заказа находится в `purchase_id[1]`, в заказах — в `order_id`.
|
||||
Соберите список заказов выбранного дня, для которых нет события покупки.
|
||||
@@ -72,7 +75,7 @@ FROM ods.order_v;
|
||||
|
||||
Если в выбранном дне повторов нет, возьмите другой закрытый день.
|
||||
|
||||
## Сопоставьте вывод с готовой сверкой
|
||||
## Сравнение с готовой витриной
|
||||
|
||||
Найдите свои заказы без события в `dm.purchase_vs_orders_v` по `order_id`.
|
||||
Сравните их `status` и `mismatch_class`. Витрина присваивает заказу один класс,
|
||||
@@ -83,7 +86,7 @@ FROM ods.order_v;
|
||||
Возьмите один заказ из своего списка и сохраните два запроса: первый находит
|
||||
его в магазине, второй показывает отсутствие покупки в трекере.
|
||||
|
||||
## Выберите источник и условие проверки
|
||||
## Выбор источника для витрины
|
||||
|
||||
По результатам сверки укажите источник для витрины, в которой должен быть
|
||||
каждый зарегистрированный заказ. Обоснуйте выбор найденными номерами.
|
||||
@@ -93,7 +96,7 @@ FROM ods.order_v;
|
||||
Позволяет ли отсутствие события в `dds.event_v` установить место потери —
|
||||
до приема в хранилище или при обработке? Какие данные нужны, чтобы это выяснить?
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] сохранен запрос сверки по дате, возвращающий заказы без события;
|
||||
- [ ] оба равенства сходятся, влияние повторного просмотра объяснено;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# Какая позиция объясняет разницу в сумме
|
||||
|
||||
**Чему учит:** разобрать вложенные данные без потери точности и локализовать
|
||||
расхождение двух источников до товарной позиции.
|
||||
Вы сравните товары в событии покупки и заказе магазина, чтобы найти причину
|
||||
разницы в суммах. При разборе вложенных данных понадобится сохранить точность
|
||||
цен до копейки.
|
||||
|
||||
Факультатив доступен после ступени 1. В DBeaver используйте пользователя
|
||||
`analyst` из [инструкции подключения](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; оставьте `world_live` на паузе и
|
||||
дождитесь уже начатых прогонов.
|
||||
|
||||
## Найдите заказ
|
||||
## Выбор заказа
|
||||
|
||||
Суммы покупки в трекере и заказа в магазине различаются. Разберите их позиции
|
||||
и проверьте отдельно точность своего запроса и различия между событием и заказом.
|
||||
@@ -24,12 +25,12 @@
|
||||
`declared_revenue`, если мы ищем расхождение именно в составе корзины?
|
||||
Проверьте свой выбор после разбора позиций.
|
||||
|
||||
## Разберите позиции с двух сторон
|
||||
## Товарные позиции события и заказа
|
||||
|
||||
Найдите событие покупки в `ods.event_v`: `purchaseID[1]` совпадает с номером
|
||||
заказа, `EventDate` — с выбранным днем, `EventType = 'purchase'`.
|
||||
Откройте поле `ecommerce`. Внутри JSON массив `purchase.products` содержит
|
||||
позиции клиента с полями `id`, `price` и `quantity`.
|
||||
товары из события покупки с полями `id`, `price` и `quantity`.
|
||||
|
||||
Разверните этот массив в строки и получите артикул, точную цену, количество
|
||||
и стоимость каждой позиции. Для разбора пригодятся `JSONExtractArrayRaw`
|
||||
@@ -47,7 +48,7 @@
|
||||
Сохраните запрос сверки для выбранных даты и номера заказа; в результате
|
||||
оставьте артикул, значения с обеих сторон и разность стоимостей позиций.
|
||||
|
||||
## Проверьте объяснение
|
||||
## Проверка сумм
|
||||
|
||||
Подтвердите три равенства:
|
||||
|
||||
@@ -66,7 +67,7 @@
|
||||
Какие строки подтверждают найденное расхождение? Есть ли в источниках
|
||||
сведения о том, почему оно возникло? Отделите наблюдения от предположений.
|
||||
|
||||
## Выберите поля для точного расчета
|
||||
## Поля для точного расчета
|
||||
|
||||
Укажите рядом с запросом, откуда брать цену, каким типом ее читать и по какому
|
||||
ключу сопоставлять позиции. Подтвердите выбор результатами обеих сверок:
|
||||
@@ -74,7 +75,7 @@
|
||||
между собой. Какой результат укажет на ошибку вашего разбора, а какой
|
||||
потребует искать причину выше — в данных, которые получил запрос?
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] сохранен запрос сверки позиций, не теряющий товары без пары;
|
||||
- [ ] все три равенства сходятся до копейки;
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
# Почему вчерашняя выручка меняется сегодня
|
||||
|
||||
**Чему учит:** обосновать окно пересчета витрины и требования к истории
|
||||
заказов по наблюдаемым опозданиям и изменениям статусов.
|
||||
Вы проследите, как опоздавшие заказы и смена статусов меняют выручку
|
||||
за прошедший день. По этим наблюдениям определите, какие дни пересчитывать
|
||||
и какую историю заказов сохранять.
|
||||
|
||||
Факультатив доступен после ступени 1. Понадобятся Airflow и DBeaver с
|
||||
подключением `student` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Он читает данные стенда и записывает ваши наблюдения в базу `default`.
|
||||
Пользователь `student` может читать данные стенда и записывать ваши наблюдения
|
||||
в базу `default`.
|
||||
Вы будете наблюдать один день оформления заказов, продвигая мир по одному
|
||||
модельному дню. Проверьте, можно ли при загрузке выручки каждый раз считать
|
||||
только новый день. Новые данные останутся в стенде.
|
||||
|
||||
## Подготовьте первое наблюдение
|
||||
## Подготовка
|
||||
|
||||
Поставьте `world_live` на паузу. Дождитесь завершения начатых прогонов
|
||||
генерации и обработки, затем запустите `etl_pipeline` и дождитесь успеха.
|
||||
@@ -28,14 +30,15 @@ SELECT
|
||||
Дата слепка, по которому сделано очередное наблюдение, будет **S**.
|
||||
Это модельные даты магазина. Календарная дата запуска Airflow день D не задает.
|
||||
|
||||
Слепок снимается к концу суток и доставляется следующим прогоном. Поэтому
|
||||
покупки последнего сыгранного дня уже видны в событиях, а их заказов в
|
||||
Слепок содержит состояние заказов на конец модельных суток и доставляется
|
||||
при следующем запуске генератора. Поэтому покупки последнего завершившегося
|
||||
дня уже видны в событиях, а их заказов в
|
||||
хранилище еще нет. Проверьте это для D в `dds.order_v` и
|
||||
`dm.purchase_vs_orders_v`.
|
||||
|
||||
## Подготовьте место для наблюдений
|
||||
## Таблицы для истории заказов
|
||||
|
||||
Публичное представление заказа показывает текущее состояние, а сырые слепки
|
||||
Представление `dds.order_v` показывает текущее состояние заказов, а сырые слепки
|
||||
хранятся ограниченное время. Сохраните историю в двух своих таблицах: потом
|
||||
вы сможете сравнивать наблюдения обычными SQL-запросами в том же DBeaver.
|
||||
|
||||
@@ -66,7 +69,7 @@ ENGINE = MergeTree
|
||||
ORDER BY (order_date, snapshot_date);
|
||||
```
|
||||
|
||||
## Сохраните первое наблюдение
|
||||
## Первое наблюдение
|
||||
|
||||
Напишите два `INSERT INTO ... SELECT` с явным списком колонок назначения:
|
||||
|
||||
@@ -93,7 +96,7 @@ ORDER BY (order_date, snapshot_date);
|
||||
статусам и сумму `items_total` только у `paid`. Эта сумма должна сходиться
|
||||
с сохраненной выручкой, сложенной по всем категориям.
|
||||
|
||||
## Продвигайте мир по одному дню
|
||||
## Наблюдения за следующие дни
|
||||
|
||||
Для каждого следующего наблюдения:
|
||||
|
||||
@@ -102,16 +105,16 @@ ORDER BY (order_date, snapshot_date);
|
||||
не обновляет.
|
||||
3. Повторите два запроса сохранения с новой датой S и проверьте записанные строки.
|
||||
|
||||
Во всех запросах остается прежний день D. За один запуск проигрывайте один
|
||||
Во всех запросах остается прежний день D. За один запуск добавляйте один
|
||||
день, чтобы сохранить промежуточные состояния. Пакетный `world_next_day`
|
||||
отправляет события без пауз; ждать 24 минуты живого дня здесь не нужно.
|
||||
|
||||
Продолжайте до слепка **D + 7** включительно. У заказов дня D окно состоит
|
||||
из семи дней, от D до D + 6. Последний шаг нужен для сравнения состояния
|
||||
в конце окна и за его пределами.
|
||||
Продолжайте до слепка **D + 7** включительно. Заказы дня D могут меняться
|
||||
семь дней, от D до D + 6. Этот период называется окном изменяемости.
|
||||
Последний шаг нужен для сравнения состояния в конце окна и после него.
|
||||
От исходного наблюдения потребуется восемь однодневных запусков.
|
||||
|
||||
## Найдите изменения в уже загруженном дне
|
||||
## Изменения заказов и выручки
|
||||
|
||||
Для сравнения прочитайте `default.lab_order_history` дважды: в одном
|
||||
подзапросе отберите прежнюю S, в другом — новую; день D остается общим.
|
||||
@@ -138,7 +141,7 @@ ORDER BY (order_date, snapshot_date);
|
||||
Достаточно ли добавлять в старый день только опоздавшие заказы? Проверьте
|
||||
свой ответ на найденных изменениях статусов.
|
||||
|
||||
## Определите, какую историю нужно хранить
|
||||
## Требования к истории заказов
|
||||
|
||||
Возьмите отмененный заказ, у которого в вашей истории был статус `paid`.
|
||||
Укажите два наблюдения, доказывающих, что он был оплачен, а затем отменен.
|
||||
@@ -153,7 +156,7 @@ ORDER BY (order_date, snapshot_date);
|
||||
Какие сведения для каждой задачи должен передавать источник и сохранять
|
||||
хранилище? Проверьте, каких нужных сведений нет в ваших таблицах наблюдений.
|
||||
|
||||
## Задайте правило пересчета
|
||||
## Правило пересчета витрины
|
||||
|
||||
Сравните сохраненные состояния при S = D + 6 и S = D + 7: состав заказов,
|
||||
их статусы, суммы и выручку. Какой слепок последним мог изменить заказы дня D
|
||||
@@ -171,13 +174,13 @@ ORDER BY (order_date, snapshot_date);
|
||||
[слепка и его доставки](../../architecture/orders/snapshot.md#слепок-и-его-доставка)
|
||||
и [границ истории отмен](../../architecture/orders/fate.md#судьба-заказа).
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] сохранена последовательность наблюдений одного дня D с датами слепков S;
|
||||
- [ ] на опоздавших заказах и изменениях статусов показаны ошибки загрузки
|
||||
только новых дней или только новых заказов;
|
||||
- [ ] изменение выручки между наблюдениями сходится с изменением вкладов заказов;
|
||||
- [ ] оплата одной из последующих отмен подтверждена двумя наблюдениями;
|
||||
- [ ] для одного отмененного заказа найдены два наблюдения: с оплатой и с отменой;
|
||||
- [ ] сформулированы требования к истории расчетов и истории оплаты;
|
||||
- [ ] правило пересчета и момент закрытия дня обоснованы наблюдениями
|
||||
и правилом доставки слепков.
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# Свой дашборд в Superset
|
||||
|
||||
**Чему учит:** собрать из своих витрин отчет о поведении посетителей,
|
||||
подобрать графики под вопросы и разместить их на одном понятном экране.
|
||||
Из своих витрин вы соберете отчет о поведении посетителей: подберете графики
|
||||
и разместите их на одном экране так, чтобы отчет можно было понять
|
||||
без ваших пояснений.
|
||||
|
||||
Это факультатив раздела «Superset и BI». Его можно пройти после ступени 2,
|
||||
Это задание раздела «Отчеты в Superset». Его можно пройти после ступени 2,
|
||||
когда готовы витрины ступени 1.
|
||||
|
||||
## На какие вопросы ответит дашборд
|
||||
## Отчет о поведении посетителей
|
||||
|
||||
Соберите обзор трафика и поведения посетителей. Он должен отвечать на три
|
||||
вопроса: что происходило в магазине, какие страницы, устройства и рекламные
|
||||
@@ -17,25 +18,23 @@
|
||||
стендового дашборда не нужно: выберите форму, в которой ответы читаются без
|
||||
пояснений рядом с экраном.
|
||||
|
||||
## Свои объекты — отдельно
|
||||
## Отдельный дашборд для задания
|
||||
|
||||
Не добавляйте графики в стендовый дашборд и не правьте его датасеты. При
|
||||
инициализации Superset импорт с `--overwrite` заменит ручные правки стендовых
|
||||
объектов файлами из репозитория. `make up` свой дашборд не стирает; срок жизни
|
||||
таких объектов описан в [доке Superset](../../architecture/superset.md), «Импорт
|
||||
таких объектов описан в [справочнике Superset](../../architecture/superset.md), «Импорт
|
||||
при каждой инициализации».
|
||||
|
||||
Используйте свои датасеты и графики, соберите из них свой дашборд.
|
||||
Назовите его, например, «Мои витрины DM». Это то же правило, по которому DDL
|
||||
домашек лежит в `sql/ddl/70-labs.sql`: стендовые объекты уже есть, свои
|
||||
создаете вы.
|
||||
Назовите его, например, «Мои витрины DM».
|
||||
|
||||
## Датасеты
|
||||
|
||||
Датасет `session_overview_v`, его метрика доли отказов и график уже готовы
|
||||
после [ступени 2](../2-1-superset-chart.md). Используйте их здесь. Добавьте
|
||||
недостающие датасеты, чтобы в подключении `ClickHouse` были представлены
|
||||
пять публичных представлений схемы `dm`:
|
||||
пять представлений ваших витрин из схемы `dm`:
|
||||
|
||||
- `events_enriched_v`;
|
||||
- `top_pages_daily_v`;
|
||||
@@ -56,7 +55,7 @@
|
||||
| `dq_errors_daily_v` | число ошибок по дню загрузки, источнику и классу |
|
||||
| `utm_effectiveness_v` | трафик, покупки и заявленную выручку по рекламным каналам |
|
||||
|
||||
Для долей используйте слагаемые из витрин. Например, доля отказов считается
|
||||
Для долей используйте суммы счетчиков из витрин. Например, доля отказов считается
|
||||
как сумма `bounce_sessions`, деленная на сумму `sessions`. Среднее по готовым
|
||||
долям для такого графика не подходит.
|
||||
|
||||
@@ -73,7 +72,7 @@
|
||||
по модельному времени. Для панели ошибок выберите период загрузки отдельно
|
||||
и укажите его в подписи. Общий фильтр времени для всего дашборда не требуется.
|
||||
|
||||
## Как проверить себя
|
||||
## Проверка результата
|
||||
|
||||
Автоматической проверки этого задания нет. Числа вы сверите запросами,
|
||||
а понятность графиков проверите по подписям.
|
||||
@@ -103,9 +102,9 @@
|
||||
Проверьте, можно ли найти эти ответы по одним подписям графиков. Если есть
|
||||
возможность, попросите другого человека прочитать экран без ваших пояснений.
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] у вас есть пять датасетов поверх публичных представлений витрин заданий 1–5;
|
||||
- [ ] у вас есть пять датасетов по представлениям витрин заданий 1–5;
|
||||
- [ ] вы собрали свой дашборд, сохранив стендовые объекты без изменений;
|
||||
- [ ] на дашборде есть хотя бы один график от каждой витрины;
|
||||
- [ ] вы проверили, что графики и подписи понятны по вопросам из раздела выше;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# В DBeaver работает, в Superset нет
|
||||
|
||||
**Чему учит:** найти причину, по которой один клиент читает объект
|
||||
хранилища, а другой его не видит.
|
||||
Вы создадите представление, которое читается из DBeaver, но недоступно
|
||||
в Superset. Затем найдете причину и исправите ее.
|
||||
|
||||
Факультатив доступен после [ступени 2](../2-1-superset-chart.md).
|
||||
Свой дашборд для опыта не нужен. Используйте готовую витрину стенда
|
||||
`dm.daily_traffic_v`.
|
||||
|
||||
## Подготовьте опыт
|
||||
## Подготовка
|
||||
|
||||
В DBeaver подключитесь к первой ноде пользователем `etl`, как описано
|
||||
в разделе [«Как применить свой DDL»](../README.md#как-применить-свой-ddl).
|
||||
В DBeaver подключитесь к первому узлу пользователем `etl`, как описано
|
||||
в разделе [«Выполнение SQL в DBeaver»](../README.md#выполнение-sql-в-dbeaver).
|
||||
Для опыта создайте отдельное представление:
|
||||
|
||||
```sql
|
||||
@@ -28,19 +28,19 @@ SELECT count() FROM dm.bi_node_probe_v;
|
||||
Повторите запрос в SQL Lab Superset, выбрав подключение `ClickHouse`.
|
||||
Сохраните текст ошибки.
|
||||
|
||||
## Найдите причину
|
||||
## Поиск причины
|
||||
|
||||
Выясните, к каким серверам обращаются DBeaver и Superset. Адреса подключения
|
||||
показывают настройки клиентов, а имя ответившего сервера можно спросить
|
||||
запросом `SELECT hostName()`.
|
||||
|
||||
Проверьте наличие `dm.bi_node_probe_v` на обеих нодах. Для второй ноды
|
||||
Проверьте наличие `dm.bi_node_probe_v` на обоих узлах. Для второго узла
|
||||
заведите подключение DBeaver с портом из
|
||||
[README](../../../README.md#подключиться-из-dbeaver). Запишите, где объект
|
||||
есть, и объясните, почему успешного создания в первом подключении оказалось
|
||||
недостаточно.
|
||||
|
||||
Исправьте DDL так, чтобы представление появилось на обеих нодах. Подключение
|
||||
Исправьте DDL так, чтобы представление появилось на обоих узлах. Подключение
|
||||
Superset должно остаться прежним. Сохраните исправленный DDL и повторите
|
||||
исходный запрос в обоих клиентах.
|
||||
|
||||
@@ -48,23 +48,23 @@ Superset должно остаться прежним. Сохраните исп
|
||||
[справочнике Superset](../../architecture/superset.md#устройство-зоны) и
|
||||
[описание распределенного DDL ClickHouse](https://clickhouse.com/docs/reference/statements/distributed-ddl).
|
||||
|
||||
## Как проверить себя
|
||||
## Проверка результата
|
||||
|
||||
В обоих клиентах запрос к вашему представлению должен вернуть столько же
|
||||
строк, сколько `SELECT count() FROM dm.daily_traffic_v`. Сравнивайте результаты
|
||||
при завершенном прогоне конвейера, пока мир не продвигается.
|
||||
|
||||
Объясните причину ошибки через три факта: куда пришел DDL, куда пришел
|
||||
запрос Superset и на каких нодах существовало представление.
|
||||
запрос Superset и на каких узлах существовало представление.
|
||||
|
||||
После опыта удалите только `dm.bi_node_probe_v` на обеих нодах. Не включайте
|
||||
После опыта удалите только `dm.bi_node_probe_v` на обоих узлах. Не включайте
|
||||
его в постоянный DDL домашних витрин: это временный объект расследования.
|
||||
|
||||
## Что должно получиться
|
||||
## Результат работы
|
||||
|
||||
- [ ] у вас сохранены успешный запрос из DBeaver и ошибка из SQL Lab;
|
||||
- [ ] вы можете объяснить, к каким серверам подключены клиенты, где было
|
||||
создано представление и почему Superset его не видел;
|
||||
- [ ] у вас есть исправленный DDL; оба клиента возвращают столько же строк,
|
||||
сколько исходная витрина;
|
||||
- [ ] после опыта вы удалили учебное представление с обеих нод.
|
||||
- [ ] после опыта вы удалили учебное представление с обоих узлов.
|
||||
Reference in new issue
Block a user