Files
clickstream-data-platform/docs/labs/optional/identity-over-time.md
T
ddadmin b839a671a1 docs(labs): добавлены история связей и инкрементальный пересчет
Зачем: дать практику учета новых связей пользователей при обновлении
прежних дней витрины.

Что: добавлены две связанные лабораторные с наблюдениями через Airflow,
собственными таблицами student и повтором частично записанной загрузки.
Обновлены программа, индекс и ссылки из справочников DDS и DM.

Проверка: DDL и SQL под student на ClickHouse 26.3.17.56, четыре модельных
дня через Airflow, полные сверки и повтор незавершенной загрузки;
config-test, lint, локальные ссылки и независимое ревью.
2026-09-22 05:57:11 -04:00

9.1 KiB
Raw Blame History

Когда хранилище узнало пользователя

Чему учит: различать время события и время появления связи в хранилище, выбирать сведения для обогащения данных на дату расчета.

Факультатив доступен после ступени 1. Понадобятся Airflow и DBeaver с подключением student по инструкции. Наблюдения сохраняйте в default через одно подключение: ваши таблицы локальны узлу. Если предложенное имя занято, выберите свое.

На сайте посетителя узнают по куке client_id, а магазин знает покупателя по user_id. Связь между ними можно установить, когда событие покупки сопоставлено с заказом. Она позволяет обогатить и прежние визиты этой куки. Вы проверите, как новый заказ меняет результат расчета за уже прошедший день.

Соберите связи с подтверждением

Поставьте world_live на паузу, дождитесь завершения начатых прогонов генерации и обработки. Запустите etl_pipeline и дождитесь успеха. На время работы мир будете продвигать вручную; новые дни останутся в стенде.

Напишите запрос по двум источникам:

Источник Нужные поля
dds.event_v event_type, event_time, client_id, purchase_id
dds.order_v order_id, user_id

В результате нужна одна строка на пару client_id, user_id и самое раннее время найденной покупки, подтверждающей эту пару. Назовите его first_purchase_at. В событии purchase массив purchase_id содержит один номер заказа. Статус заказа не ограничивайте: отмена покупки не меняет владельца куки.

Источники распределены по разным ключам. Для соединения используйте GLOBAL INNER JOIN, заключив выборки событий и заказов в подзапросы. Устройство источников описано в карте идентичностей.

Проверьте уникальность пар и совпадение их полного набора с dds.identity_map_v: одного равенства количества недостаточно. Для одной пары покажите номера заказов и события, по которым нашли время.

Сохраните три наблюдения

Создайте таблицу:

CREATE TABLE default.lab_identity_history
(
    observation_day Date,
    client_id UInt64,
    user_id UInt64,
    first_purchase_at DateTime('Europe/Samara')
)
ENGINE = MergeTree
ORDER BY (observation_day, client_id, user_id);

Для метки наблюдения используйте последний обработанный день событий:

SELECT max(event_date) AS observation_day FROM dds.event_v;

Обозначим начальную дату H0. Это модельная дата, а не календарный день запуска Airflow. После успешного etl_pipeline сохраните полный результат своего запроса через INSERT INTO ... SELECT, добавив эту дату. Проверьте число строк и уникальность пар за H0.

Затем дважды выполните последовательность:

  1. Запустите world_next_day с days = 1 и дождитесь успеха.
  2. Запустите etl_pipeline и дождитесь успеха.
  3. Получите новую observation_day, сохраните полный набор связей и проверьте его.

Получатся наблюдения H0, H1 и H2. Каждую дату записывайте один раз: обычный MergeTree не устраняет повторы вставки. Между этими действиями не запускайте генерацию отдельно от наблюдения.

Сопоставьте два времени

Сравните наборы пар в соседних наблюдениях. Для нескольких новых связей покажите client_id, user_id, first_purchase_at и первую дату наблюдения, в которой пара появилась. Найдите связь, покупка которой произошла до дня ее обнаружения.

Для одной такой связи вернитесь к заказу и событию. По данным и порядку доставки заказов объясните, почему связь отсутствовала в прежнем наблюдении. Был ли момент покупки достаточным основанием считать ее уже известной хранилищу?

У пары, которая присутствовала уже в H0, тоже получится минимальная дата наблюдения. В этом случае она означает «пара была известна к началу опыта»: истории до H0 у вас нет. Для новых пар ежедневные наблюдения устанавливают интервал появления связи, а не точное время внутри него.

Пересчитайте прежние визиты

Возьмите один и тот же набор сессий из dds.session_v за даты до H0 включительно. Постройте два дневных расчета:

  • со связями, сохраненными в H0;
  • со связями, сохраненными в H2.

Для каждого дня посчитайте посетителей по разным client_id и известных пользователей по разным user_id. Сессии без связи должны остаться в расчете, но неизвестный пользователь не должен увеличивать число известных. В соединении распределенных сессий с локальной историей используйте GLOBAL LEFT JOIN и заранее отберите в истории одну дату наблюдения.

Найдите день с разным числом известных пользователей. Проследите изменение до конкретных связей и прежних сессий. Проверьте, что число посетителей не изменилось и известные пользователи не превышают его.

Напишите, какой вариант нужен для двух требований к витрине:

  • «пересчитать прошлые визиты с учетом всех сведений, доступных сейчас»;
  • «воспроизвести расчет, сделанный при наблюдении H0».

Для второго требования проверьте еще один способ: взять текущие связи, оставив только first_purchase_at до конца H0. Совпадет ли полный набор пар с сохраненным в H0? Найденным расхождением обоснуйте выбор истории для воспроизводимого расчета.

Что должно получиться

У вас есть запрос связей с подтверждающими покупками, три сохраненных наблюдения и сравнение двух расчетов на одном наборе сессий. Вы можете показать, когда новая связь стала видна в наблюдениях, и объяснить, какие данные понадобятся для воспроизведения прежнего расчета.

Сохраните SQL и таблицу наблюдений: они нужны в продолжении «Как обновлять витрину без полной пересборки». Если продолжать не планируете, удалите свою таблицу через DROP TABLE.