docs(warehouse): объяснены расчет строк и замена дневных разделов

Зачем: выражения «собираются в донор» и «публикуются дни» требовали
знать устройство конвейера до чтения объяснения.

Что: описаны назначение промежуточных таблиц и последовательность
расчета, записи и замены разделов. Перечитаны остальные объяснения:
выбор дней, разворачивание позиций заказа, проверка сессий и повтор запуска.

Проверка: make lint, git diff --check, локальные ссылки и якоря.
SQL без комментариев и AST обоих дагов без строк документации не изменились.

Refs: #249
This commit is contained in:
ddadmin committed 2026-09-13 15:16:26 -04:00
1 parent 5f317ba8d2
commit 086007fbd4
12 files changed
+216 -166

No files matched your search

+8 -5
View File
@@ -1,16 +1,19 @@
-- DDS: сборка сессий выбранных дней в донор dds.session_stage_dist.
-- Донор очищается целиком; одна вставка собирает весь диапазон.
-- DDS: расчет сессий за дни от first_day до last_day включительно.
-- Сначала очищаем промежуточную таблицу session_stage_rep, затем записываем
-- в нее рассчитанные строки через session_stage_dist. Основная session_rep
-- остается прежней до выполнения session_replace.sql.
--
-- Первое окно помечает событие единицей, если с предыдущего события того же
-- посетителя за тот же день прошло больше 1800 секунд. Второе окно суммирует
-- эти единицы: получается номер визита внутри посетителя и дня.
-- PARTITION BY (client_id, event_date) разделяет визиты по модельной полночи.
-- эти единицы: получается номер визита для каждого посетителя за день.
-- PARTITION BY (client_id, event_date) считает каждый модельный день отдельно:
-- события разных дней не попадут в одну сессию даже при короткой паузе.
-- Учитываются все типы событий.
--
-- У первого события lagInFrame возвращает его собственное время: разница
-- равна нулю, opens_visit = 0, и первый visit_no тоже равен нулю.
-- Оба окна используют (event_time, event_id), чтобы при равном времени
-- признак начала и накопленный номер визита относились к одним событиям.
-- отметка начала и номер визита относились к одним событиям.
-- Порог 1800 секунд — правило визита; он не передается параметром.
ALTER TABLE dds.session_stage_rep ON CLUSTER clickstream_cluster DROP PARTITION ALL;
+4 -3
View File
@@ -1,7 +1,8 @@
-- DDS: замена одного дня в session_rep готовой партицией session_stage_rep.
-- DDS: заменяем раздел session_rep за выбранный день готовым разделом
-- промежуточной session_stage_rep. Раздел таблицы называется партицией.
-- ON CLUSTER выполняет замену на локальных таблицах каждого шарда.
-- Замена атомарна на одном шарде, общей транзакции для кластера нет.
-- Повтор с тем же донором не добавляет копий строк.
-- На одном шарде раздел меняется целиком; общей транзакции для кластера нет.
-- Повтор с теми же строками session_stage_rep не добавляет копий в session_rep.
--
-- Дату из session_scope.sql подставляет Jinja: параметр ClickHouse в
-- ALTER ... PARTITION здесь не поддерживается. Поиск дней следующего
+5 -4
View File
@@ -1,5 +1,5 @@
-- DDS: дни для сборки сессий, от first_day до last_day включительно.
-- Пустой ответ означает пустой ODS; NULL в first_day — отсутствие работы.
-- Без событий ODS строк в ответе нет; NULL в first_day — дней для расчета нет.
--
-- position — номер следующего дня для генерации. Последний прожитый день
-- равен min(EventDate) + position - 1. В отличие от max(EventDate), эта
@@ -13,9 +13,10 @@
WITH
(SELECT min(EventDate) FROM ods.event_dist) AS first_source_day,
first_source_day + ({position:UInt16} - 1) AS last_lived_day,
-- Ищем первый день ODS, которого нет в DDS: максимум собранного дня
-- пропустил бы более ранний пробел. Частично заполненный день так не найти.
-- GLOBAL сравнивает со списком дней всего DDS, а не одного шарда.
-- Ищем первую дату событий ODS, за которую еще нет сессий DDS.
-- Поиск после max(session_date) пропустил бы более раннюю потерянную дату.
-- Если за день есть хотя бы одна сессия, он уже не считается пропущенным.
-- GLOBAL берет даты сессий со всех шардов.
-- minOrNull возвращает NULL, если пропусков нет.
(
SELECT minOrNull(day)
+6 -4
View File
@@ -1,7 +1,9 @@
-- DM: сборка выручки за выбранный диапазон в донор.
-- DROP PARTITION ALL очищает донор на каждом узле. Вставка ниже дает
-- одну строку на день заказа и категорию товара: только оплаченные заказы.
-- ARRAY JOIN разворачивает согласованные позиции трех массивов вместе.
-- DM: расчет выручки за дни от first_day до last_day включительно.
-- DROP PARTITION ALL очищает промежуточную revenue_daily_stage_rep.
-- Затем INSERT записывает по одной строке итогов на день и категорию товара.
-- Основная revenue_daily_rep остается прежней до revenue_daily_replace.sql.
-- В расчет входят только оплаченные заказы. ARRAY JOIN превращает артикул,
-- количество и цену с одним индексом в массивах в одну строку позиции заказа.
-- Причина выбора DROP вместо TRUNCATE — в sql/dds/order_rebuild.sql.
ALTER TABLE dm.revenue_daily_stage_rep ON CLUSTER clickstream_cluster
DROP PARTITION ALL;
+4 -3
View File
@@ -1,8 +1,9 @@
-- DM: замена дня выручки готовой партицией донора.
-- DM: заменяем раздел revenue_daily_rep за выбранный день готовым разделом
-- промежуточной revenue_daily_stage_rep. Раздел таблицы называется партицией.
-- Дату из revenue_daily_scope.sql подставляет Jinja: параметр ClickHouse
-- в ALTER ... PARTITION здесь не поддерживается.
-- ON CLUSTER выполняет замену на локальных таблицах каждого шарда.
-- Замена атомарна на одном шарде, общей транзакции для кластера нет.
-- Повтор с тем же донором не добавляет копий строк.
-- На одном шарде раздел меняется целиком; общей транзакции для кластера нет.
-- Повтор с теми же строками промежуточной таблицы не добавляет копий в основной.
ALTER TABLE dm.revenue_daily_rep ON CLUSTER clickstream_cluster
REPLACE PARTITION '{{ params.day }}' FROM dm.revenue_daily_stage_rep;
+2 -2
View File
@@ -1,6 +1,6 @@
-- DM: диапазон пересборки выручки, first_day и last_day включительно.
-- Последний слепок ODS задает даты оформления еще изменяемых заказов.
-- Агрегат читает DDS; ODS нужен только для границ диапазона.
-- Последний слепок ODS задает даты оформления заказов, которые еще могут
-- измениться. Саму выручку считаем по DDS; ODS нужен только для выбора дат.
-- Левая граница расширяется до первого дня с оплаченными заказами DDS,
-- которого нет в витрине. Так первый запуск охватывает историю выручки.
-- По наличию даты нельзя обнаружить частично заполненный день.