From 70a9aeddb797f558f97ca7586216849512c7b9ac Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Tue, 25 Aug 2026 04:40:30 -0400 Subject: [PATCH 1/4] =?UTF-8?q?docs(dm):=20=D1=81=D0=BF=D1=80=D0=BE=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=81=D0=BB?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=B2=D0=B8=D1=82=D1=80=D0=B8=D0=BD=20DM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - развилка #135 карты #127 решена: форма и состав витрин DM, контур DQ этапа 4; резолюция переносится в доки architecture. - Что: - создана docs/architecture/dm.md: форма по зерну, дележ витрин между стендом и заданиями менти, dq_summary с REPLACE PARTITION, звено DQ конвейера и даг самопроверки домашек. - ссылки на #135 в etl.md и dds/README.md заменены на доку слоя. - Проверка: - make config-test. Co-Authored-By: Claude Fable 5 --- docs/architecture/dds/README.md | 4 -- docs/architecture/dm.md | 121 ++++++++++++++++++++++++++++++++ docs/architecture/etl.md | 10 +-- 3 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 docs/architecture/dm.md diff --git a/docs/architecture/dds/README.md b/docs/architecture/dds/README.md index 6308b32..b447f43 100644 --- a/docs/architecture/dds/README.md +++ b/docs/architecture/dds/README.md @@ -54,10 +54,6 @@ - Наполняет слой [дневной конвейер](../etl.md): запуск, объём прогона и замена партиций на кластере — его устройство. -## Открытые решения - -- Витрины DM — #135. - ## Родословная Дом набора и первая сущность собраны развилкой #130 карты #127; форма diff --git a/docs/architecture/dm.md b/docs/architecture/dm.md new file mode 100644 index 0000000..5338702 --- /dev/null +++ b/docs/architecture/dm.md @@ -0,0 +1,121 @@ +# Слой DM: витрины + +Как модель DDS превращается в витрины для потребителя BI: какую форму +принимает витрина, кто какие витрины строит и как слой проверяется. Состав +колонок каждой витрины задаёт раздел 7 мастер-спеки; здесь — форма, +наполнение и контроль. + +## Форма: по зерну, не по цене запроса + +Витрина, меняющая зерно источника — дневной агрегат, сверка по заказам, — +материализуется: `dm.<имя>_rep` / `_dist` и публичное `dm.<имя>_v` с явным +списком колонок, по общим [конвенциям хранилища](storage.md). Наполняет её +`dm_transform` заменой дневных партиций дышащего окна K — той же механикой, +что у сущностей DDS ([конвейер](etl.md)). Витрина, сохраняющая зерно +источника — переименование, обогащение строки, — остаётся обычным +представлением: копию событий ради других имён колонок не держит ни один +боевой склад. + +Правило выбрано учебной целью, а не ценой запроса. На объёмах стенда +представлениями обошлось бы всё: условия сквозь цепочку представлений +проходят ([исследование](../research/2026-08-22-view-predicate-pushdown.md)). +Но агрегат, пересобираемый партициями, — производственный паттерн, ради +которого стенд и строится, а пара «таблица рядом с представлением» +показывает: форма — решение по роли витрины, у одного слоя законны обе. + +## Кто строит: стенд и менти + +Стенд привозит готовыми витрины трёх сюжетов дашборда этапа 8 и +инфраструктуру контроля: + +- `revenue_daily` — выручка по дням и категориям; образец материализованной + витрины, на него ссылаются учебные задания; +- `purchase_vs_orders` — сверка A+C с классами расхождений; зерно — заказ, + шардирование сохраняет ко-локацию заказов по `cityHash64(order_id)`; +- `daily_traffic` — пара «посетители» / «известные пользователи», локальное + обогащение картой идентичностей; +- `dq_summary` — сводка проверок качества (ниже). + +Остальные витрины спеки — учебные задания: менти строит их сам по ТЗ с +образцом. Разминка — представление `events_enriched_v` (зерно события), +затем агрегаты `top_pages_daily`, `session_overview` и `dq_errors_daily`, +последней — самая содержательная `utm_effectiveness` с уроком `declared_*`. + +Дашборд этапа 8 стоит только на витринах стенда: приёмка этапа не зависит +от выполненных домашек. Расширение дашборда визуализациями по своим +витринам — отдельная домашка после этапа 8. + +## `dm.dq_summary` + +Зерно — «день данных × проверка»: строка отвечает, каково качество дня +сейчас, а не сколько раз его проверяли, — история прогонов и так живёт в +Airflow. Партиция — день данных; прогон звена DQ заменяет партиции +проверенных дней через `REPLACE PARTITION`. Обещанный спекой перевод с +`TRUNCATE+INSERT` выполняется той же механикой замены, что и у витрин, — +ничего отдельного учить не надо. + +## Звено DQ конвейера + +Встаёт в `etl_pipeline` после DM ([конвейер](etl.md)) и проверяет только +объекты стенда: + +- счётная сверка сессий с эталоном `VisitID` — кука × день, эталон читается + из `ods.event_v` ([модель сессии](dds/session.md)); +- счётчики классов расхождений против описи мира — по дням с закрытым + окном; +- счётные сверки витрин стенда с их DDS-источниками. + +Результаты ложатся в `dm.dq_summary`. Звено — не только сторож конвейера, +но и экспонат: менти видит, как контроль качества устроен в бою — по +расписанию, с историей, рядом с трансформациями. + +## Даг самопроверки + +Домашки контролирует отдельный даг без расписания: менти запускает его +рукой. Задача витрины красная, пока витрины нет или счёт не сходится, и +зелёная, когда построено верно; сообщение об ошибке говорит, что не так и +куда смотреть. Проверки — инварианты против DDS-источников, золотые +константы не прибиваются. В `dq_summary` даг не пишет: он инструмент лабы, +а не история качества конвейера. + +Приём проверен на greenplum-стенде предшественника: валидационный даг с +группами проверок по слоям давал менти обратную связь по каждому шагу +домашки, не трогая рабочий конвейер. + +## Остаётся нарезке + +- Имена задач `dm_transform`, звена DQ и дага самопроверки. +- Ключи шардирования материализованных витрин — вместе с их DDL; правило + партиции-донора — в [доке хранилища](storage.md). +- Тексты учебных заданий и точный список проверок обоих контуров. +- Механика сверки A+C в SQL — рамка в спеке, разделы 4 и 7. + +## Отклонённые варианты + +- **Весь слой представлениями.** Дёшево и всегда свежо, но главный + производственный паттерн слоя — пересборка агрегатов — остался бы + невидим, а `dm_transform` — без работы. +- **Материализовать всё.** Копия событий ради переименования колонок — + антипаттерн, который менти увёз бы в бой. +- **Гибрид по цене запроса.** Выбор формы по стоимости, которой на объёмах + стенда нет: сторож без настоящей опасности. +- **Проверки домашек в конвейерном звене DQ.** Конвейер стоял бы красным до + выполнения лаб, а проверка, которая всегда красная, приучает себя + игнорировать. +- **«Жёлтый» статус недостроенной витрины.** У задачи Airflow нет такого + состояния; изображать его логами — семантика, которую пришлось бы + расшифровывать. Красное «ещё не построено» честнее. +- **Самопроверка пишет в `dq_summary`.** Попытки менти смешались бы с + историей качества конвейера. +- **Superset поверх DDS без слоя DM.** Терялся бы урок «витрина — контракт + под потребителя», против раздела 7 спеки. + +## Связанные решения + +- Мастер-спека, разделы 4 и 7, — состав колонок витрин и классы сверки. +- [Дневной конвейер](etl.md) — запуск `dm_transform`, объём прогона, + замена партиций на кластере. +- [Дока хранилища](storage.md) — имена объектов, граница доступа через + `_v`, партиция-донор. +- [Карта модели DDS](dds/README.md) — источники витрин. +- Резолюция — тикет #135 карты #127. diff --git a/docs/architecture/etl.md b/docs/architecture/etl.md index 41a4d42..cd8adea 100644 --- a/docs/architecture/etl.md +++ b/docs/architecture/etl.md @@ -14,8 +14,8 @@ Дневной конвейер на стенде один — даг `etl_pipeline`. Своей работы у него нет: он дёргает слойные даги последовательно и ждёт каждый — -`dds_transform`, затем `dm_transform`. Контур DQ этапа 4 встанет его же -звеном после DM; состав звена — предмет развилки витрин (#135) и нарезки. +`dds_transform`, затем `dm_transform`. Контур DQ этапа 4 встаёт его же +звеном после DM; состав звена — в [доке слоя DM](dm.md). Слойные даги устроены по образцу `orders_ingest`: без расписания, один активный прогон, запускаются триггером конвейера или рукой при разборе @@ -42,7 +42,8 @@ Параметров у конвейера нет: объём он выводит сам из `world_position` и состояния слоёв. Сессии догоняют хвост — от последнего собранного дня до последнего прожитого; заказы пересобирают дышащее окно K от позиции; карта -идентичностей пересчитывается целиком; правила витрин — у витрин (#135). +идентичностей пересчитывается целиком; правила витрин — у +[слоя DM](dm.md). Поэтому один и тот же запуск одинаково верен из триггера, с кнопки менти и после падения, а разгону на семь дней хватает одного прогона. @@ -70,7 +71,8 @@ диапазон, включая форму необязательных параметров того же дага, — этап 5 (#7); туда же стык #111 про дату модельного мира и `logical_date`. - Инкрементальный ETL вместо пересборки — техдолг #2. -- Состав витрин `dm_transform` и звена DQ — #135 и нарезка этапа 4. +- Состав витрин `dm_transform` и звена DQ — [дока слоя DM](dm.md); + имена задач — нарезка этапа 4. ## Отклонённые варианты From 99496971e24850341e9f6cb71dea391c172b97e8 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Tue, 25 Aug 2026 04:57:17 -0400 Subject: [PATCH 2/4] =?UTF-8?q?docs(dm):=20=D0=B2=D1=8B=D1=87=D0=B8=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=B0=20=D0=B4=D0=BE=D0=BA=D0=B0=20=D1=81=D0=BB?= =?UTF-8?q?=D0=BE=D1=8F=20=D0=B2=D0=B8=D1=82=D1=80=D0=B8=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - горячее ревью развилки #135 нашло два незакрытых решения: объём пересборки витрин и судьба менти-витрины после постройки. - Что: - добавлен раздел «Объём пересборки»: одно окно K для всех витрин, замерзание daily_traffic за окном названо решением с объяснением. - в ТЗ менти добавлен финальный пункт — встроить витрину в dm_transform. - поправлены мелочи: greenplum-стенд больше не зовётся предшественником, добавлены ссылки на спеку и карту идентичностей. - Проверка: - make config-test. Co-Authored-By: Claude Fable 5 --- docs/architecture/dm.md | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/architecture/dm.md b/docs/architecture/dm.md index 5338702..c56cb26 100644 --- a/docs/architecture/dm.md +++ b/docs/architecture/dm.md @@ -10,8 +10,8 @@ Витрина, меняющая зерно источника — дневной агрегат, сверка по заказам, — материализуется: `dm.<имя>_rep` / `_dist` и публичное `dm.<имя>_v` с явным списком колонок, по общим [конвенциям хранилища](storage.md). Наполняет её -`dm_transform` заменой дневных партиций дышащего окна K — той же механикой, -что у сущностей DDS ([конвейер](etl.md)). Витрина, сохраняющая зерно +`dm_transform` заменой дневных партиций — той же механикой, что у сущностей +DDS ([конвейер](etl.md)); объём пересборки — ниже. Витрина, сохраняющая зерно источника — переименование, обогащение строки, — остаётся обычным представлением: копию событий ради других имён колонок не держит ни один боевой склад. @@ -33,18 +33,38 @@ - `purchase_vs_orders` — сверка A+C с классами расхождений; зерно — заказ, шардирование сохраняет ко-локацию заказов по `cityHash64(order_id)`; - `daily_traffic` — пара «посетители» / «известные пользователи», локальное - обогащение картой идентичностей; + обогащение [картой идентичностей](dds/identity.md); - `dq_summary` — сводка проверок качества (ниже). Остальные витрины спеки — учебные задания: менти строит их сам по ТЗ с образцом. Разминка — представление `events_enriched_v` (зерно события), затем агрегаты `top_pages_daily`, `session_overview` и `dq_errors_daily`, последней — самая содержательная `utm_effectiveness` с уроком `declared_*`. +Построенная витрина встаёт в конвейер руками менти: финальный пункт +каждого ТЗ — добавить задачу своей витрины в `dm_transform`. До этого +конвейер о ней не знает и остаётся зелёным, после — витрина пересобирается +наравне со стендовыми. Дашборд этапа 8 стоит только на витринах стенда: приёмка этапа не зависит от выполненных домашек. Расширение дашборда визуализациями по своим витринам — отдельная домашка после этапа 8. +## Объём пересборки + +Все материализованные витрины пересобираются одним окном — дышащим окном K +от позиции мира, тем же, что у заказов. Витринам от заказов окна хватает по +построению: день за окном закрыт, его классы и суммы не меняются. Витринам +от событий и сессий окно даже избыточно — их дни замерзают сразу. + +Одно следствие названо явно. `daily_traffic` обогащается картой +идентичностей, а карта пересчитывается целиком, и склейка ретроспективна: +покупка сегодня делает куку «известной» во всех прошлых днях карты. Дни за +окном K в витрину эту новость уже не получат — они хранят число известных +на момент закрытия окна. Это решение, а не недосмотр: живое окно показывает +текущую склейку, замороженные дни — какой она была тогда, и расхождение +между витриной и картой само по себе урок ретроспективности (историю +склейки стенд сознательно не хранит — issue #145). + ## `dm.dq_summary` Зерно — «день данных × проверка»: строка отвечает, каково качество дня @@ -78,14 +98,15 @@ Airflow. Партиция — день данных; прогон звена DQ константы не прибиваются. В `dq_summary` даг не пишет: он инструмент лабы, а не история качества конвейера. -Приём проверен на greenplum-стенде предшественника: валидационный даг с +Приём проверен на соседнем учебном стенде Airflow + Greenplum: валидационный даг с группами проверок по слоям давал менти обратную связь по каждому шагу домашки, не трогая рабочий конвейер. ## Остаётся нарезке - Имена задач `dm_transform`, звена DQ и дага самопроверки. -- Ключи шардирования материализованных витрин — вместе с их DDL; правило +- Ключи шардирования остальных материализованных витрин — вместе с их + DDL; правило партиции-донора — в [доке хранилища](storage.md). - Тексты учебных заданий и точный список проверок обоих контуров. - Механика сверки A+C в SQL — рамка в спеке, разделы 4 и 7. @@ -112,7 +133,8 @@ Airflow. Партиция — день данных; прогон звена DQ ## Связанные решения -- Мастер-спека, разделы 4 и 7, — состав колонок витрин и классы сверки. +- [Мастер-спека](../specs/2026-07-30-stand-v2-realism.md), разделы 4 и 7, — + состав колонок витрин и классы сверки. - [Дневной конвейер](etl.md) — запуск `dm_transform`, объём прогона, замена партиций на кластере. - [Дока хранилища](storage.md) — имена объектов, граница доступа через From 92d834761c935c1247e63989e861f298c5d5ee9f Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Tue, 25 Aug 2026 06:33:10 -0400 Subject: [PATCH 3/4] =?UTF-8?q?docs(dm):=20=D1=80=D0=B8=D1=82=D0=BC=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B2=D0=B8=D1=82=D1=80=D0=B8=D0=BD=20=D0=B2=D1=8B=D0=B2=D0=B5?= =?UTF-8?q?=D0=B4=D0=B5=D0=BD=20=D0=B8=D0=B7=20=D0=BF=D0=BE=D0=B4=D0=B2?= =?UTF-8?q?=D0=B8=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - обсуждение горячего ревью показало: «окно K для всех» — ритм заказов, натянутый на слой, а замерзание daily_traffic обесценивало витрину. - Что: - раздел «Объём пересборки» заменён «Ритмом пересборки»: три ритма — хвост / окно K / целиком; daily_traffic наследует у карты полный пересчёт в ReplacingMergeTree, дневные партиции ей не положены. - в отклонённые добавлены замерзание за окном K и инкремент по first_matched_at; инкремент стал идеей лабы повышенной сложности #149. - Проверка: - make config-test. Co-Authored-By: Claude Fable 5 --- docs/architecture/dm.md | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/architecture/dm.md b/docs/architecture/dm.md index c56cb26..d59881d 100644 --- a/docs/architecture/dm.md +++ b/docs/architecture/dm.md @@ -10,8 +10,7 @@ Витрина, меняющая зерно источника — дневной агрегат, сверка по заказам, — материализуется: `dm.<имя>_rep` / `_dist` и публичное `dm.<имя>_v` с явным списком колонок, по общим [конвенциям хранилища](storage.md). Наполняет её -`dm_transform` заменой дневных партиций — той же механикой, что у сущностей -DDS ([конвейер](etl.md)); объём пересборки — ниже. Витрина, сохраняющая зерно +`dm_transform`; ритм и механика пересборки — ниже. Витрина, сохраняющая зерно источника — переименование, обогащение строки, — остаётся обычным представлением: копию событий ради других имён колонок не держит ни один боевой склад. @@ -49,21 +48,27 @@ DDS ([конвейер](etl.md)); объём пересборки — ниже. от выполненных домашек. Расширение дашборда визуализациями по своим витринам — отдельная домашка после этапа 8. -## Объём пересборки +## Ритм пересборки -Все материализованные витрины пересобираются одним окном — дышащим окном K -от позиции мира, тем же, что у заказов. Витринам от заказов окна хватает по -построению: день за окном закрыт, его классы и суммы не меняются. Витринам -от событий и сессий окно даже избыточно — их дни замерзают сразу. +Партиция витрины пересобирается, пока может измениться её источник, — +поэтому ритмов три, по числу источников: -Одно следствие названо явно. `daily_traffic` обогащается картой -идентичностей, а карта пересчитывается целиком, и склейка ретроспективна: -покупка сегодня делает куку «известной» во всех прошлых днях карты. Дни за -окном K в витрину эту новость уже не получат — они хранят число известных -на момент закрытия окна. Это решение, а не недосмотр: живое окно показывает -текущую склейку, замороженные дни — какой она была тогда, и расхождение -между витриной и картой само по себе урок ретроспективности (историю -склейки стенд сознательно не хранит — issue #145). +- **от событий и сессий** — день замерзает сразу; пересборка догоняет + хвост несобранных дней заменой дневных партиций; +- **от заказов** — день дышит окном K и закрывается; пересборка заменяет + партиции окна, дни за ним закрыты по построению; +- **от карты идентичностей** — не замерзает никогда: склейка + ретроспективна, покупка сегодня делает куку известной во всех её прошлых + днях, а карта пересчитывается целиком. + +Поэтому `daily_traffic` наследует у своего источника и ритм, и механику: +полный пересчёт всех дней каждый прогон в `ReplacingMergeTree(_load_ts)`, +как у самой карты. Дневные партиции ей не положены — строка в дне одна, и +партиция на строку плодила бы микрокуски на ровном месте. Пересчёт дешёв: +витрина читает сессии и карту локальным соединением по ключу ко-локации. +Пересчитывать точечно только затронутые дни не из чего: для этого надо +знать, какие связки новые, а полный пересчёт карты этот след затирает — +восстановление следа оставлено лабе повышенной сложности (issue #149). ## `dm.dq_summary` @@ -128,6 +133,14 @@ Airflow. Партиция — день данных; прогон звена DQ расшифровывать. Красное «ещё не построено» честнее. - **Самопроверка пишет в `dq_summary`.** Попытки менти смешались бы с историей качества конвейера. +- **Окно K для `daily_traffic` — прошлое замерзает.** Дни за окном хранили + бы число известных на момент закрытия — витрина тихо расходится с картой + и протаскивает обратно «знание на дату», отвергнутое развилкой карты + (#133). +- **Инкрементальный пересчёт затронутых дней по `first_matched_at`.** + Производственный ход, но на объёмах стенда он экономит неизмеримое, а + след новых связок требует вернуть колонку, выкинутую в #133. Стал лабой + повышенной сложности — issue #149. - **Superset поверх DDS без слоя DM.** Терялся бы урок «витрина — контракт под потребителя», против раздела 7 спеки. From 2f9a26eb0eca83f6b948f3fc4711e933917018b5 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Tue, 25 Aug 2026 06:37:09 -0400 Subject: [PATCH 4/4] =?UTF-8?q?docs(dm):=20=D0=B2=D1=8B=D1=87=D0=B8=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=20=D1=81=D0=BB=D0=BE=D0=B9=20=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=20=D0=B2=D1=82=D0=BE=D1=80=D1=8B=D0=BC=20?= =?UTF-8?q?=D0=B3=D0=BE=D1=80=D1=8F=D1=87=D0=B8=D0=BC=20=D1=80=D0=B5=D0=B2?= =?UTF-8?q?=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - после переписывания ритма пересборки в тексте остались швы прежних формулировок и один разрыв с докой конвейера. - Что: - довод против дневных партиций daily_traffic заменён верным: партиция — единица замены, а витрина заменяется только целиком (число строк тут ни при чём, иначе довод бил бы и по dq_summary). - в etl.md к механике REPLACE PARTITION добавлена вторая идемпотентность конвейера — полная перезапись в ReplacingMergeTree. - правило ритмов говорит про день, а не партицию; поправлены переносы строк и обороты. - Проверка: - make config-test. Co-Authored-By: Claude Fable 5 --- docs/architecture/dm.md | 19 +++++++++---------- docs/architecture/etl.md | 4 +++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/architecture/dm.md b/docs/architecture/dm.md index d59881d..7371074 100644 --- a/docs/architecture/dm.md +++ b/docs/architecture/dm.md @@ -18,7 +18,7 @@ Правило выбрано учебной целью, а не ценой запроса. На объёмах стенда представлениями обошлось бы всё: условия сквозь цепочку представлений проходят ([исследование](../research/2026-08-22-view-predicate-pushdown.md)). -Но агрегат, пересобираемый партициями, — производственный паттерн, ради +Но пересборка агрегатов конвейером — производственный паттерн, ради которого стенд и строится, а пара «таблица рядом с представлением» показывает: форма — решение по роли витрины, у одного слоя законны обе. @@ -50,7 +50,7 @@ ## Ритм пересборки -Партиция витрины пересобирается, пока может измениться её источник, — +День витрины пересобирается, пока может измениться его источник, — поэтому ритмов три, по числу источников: - **от событий и сессий** — день замерзает сразу; пересборка догоняет @@ -63,8 +63,8 @@ Поэтому `daily_traffic` наследует у своего источника и ритм, и механику: полный пересчёт всех дней каждый прогон в `ReplacingMergeTree(_load_ts)`, -как у самой карты. Дневные партиции ей не положены — строка в дне одна, и -партиция на строку плодила бы микрокуски на ровном месте. Пересчёт дешёв: +как у самой карты. Дневных партиций у неё нет: партиция — единица замены, +а эта витрина заменяется только целиком. Пересчёт дешёв: витрина читает сессии и карту локальным соединением по ключу ко-локации. Пересчитывать точечно только затронутые дни не из чего: для этого надо знать, какие связки новые, а полный пересчёт карты этот след затирает — @@ -103,16 +103,15 @@ Airflow. Партиция — день данных; прогон звена DQ константы не прибиваются. В `dq_summary` даг не пишет: он инструмент лабы, а не история качества конвейера. -Приём проверен на соседнем учебном стенде Airflow + Greenplum: валидационный даг с -группами проверок по слоям давал менти обратную связь по каждому шагу -домашки, не трогая рабочий конвейер. +Приём проверен на соседнем учебном стенде Airflow + Greenplum: +валидационный даг с группами проверок по слоям давал менти обратную связь +по каждому шагу домашки, не трогая рабочий конвейер. ## Остаётся нарезке - Имена задач `dm_transform`, звена DQ и дага самопроверки. - Ключи шардирования остальных материализованных витрин — вместе с их - DDL; правило - партиции-донора — в [доке хранилища](storage.md). + DDL; правило партиции-донора — в [доке хранилища](storage.md). - Тексты учебных заданий и точный список проверок обоих контуров. - Механика сверки A+C в SQL — рамка в спеке, разделы 4 и 7. @@ -138,7 +137,7 @@ Airflow. Партиция — день данных; прогон звена DQ и протаскивает обратно «знание на дату», отвергнутое развилкой карты (#133). - **Инкрементальный пересчёт затронутых дней по `first_matched_at`.** - Производственный ход, но на объёмах стенда он экономит неизмеримое, а + Производственный ход, но на объёмах стенда его экономия неизмерима, а след новых связок требует вернуть колонку, выкинутую в #133. Стал лабой повышенной сложности — issue #149. - **Superset поверх DDS без слоя DM.** Терялся бы урок «витрина — контракт diff --git a/docs/architecture/etl.md b/docs/architecture/etl.md index cd8adea..4ce9370 100644 --- a/docs/architecture/etl.md +++ b/docs/architecture/etl.md @@ -63,7 +63,9 @@ вставка через Distributed раскладывает строки по шардам, — затем `REPLACE PARTITION` на кластере атомарно подменяет кусок каждого шарда. Эта механика — часть самих трансформаций и строится этапом 4: без неё дневной -прогон не повторяем. +прогон не повторяем. Сущности, пересчитываемые целиком, идемпотентны и без +замены: полная перезапись в `ReplacingMergeTree` — так живут карта +идентичностей и витрина `daily_traffic` ([слой DM](dm.md)). ## Не входит