docs(dds): зафиксирована физическая модель карты идентичностей

- Зачем:
  - согласованная модель нужна для пакетной реализации DDS и понятного публичного интерфейса слоя.
- Что:
  - описаны физическая карта идентичностей, полный пересчёт и отказ от first_matched_at.
  - унифицирован публичный контракт _v для событий, заказов, сессий и карты.
  - синхронизированы мастер-спека, имена объектов и граница доступа.
- Проверка:
  - git diff --cached --check.
This commit is contained in:
ddadmin committed 2026-08-24 15:52:17 -04:00
1 parent 256d51840b
commit f0c4b4c627
7 files changed
+234 -59

No files matched your search

+18 -12
View File
@@ -38,18 +38,22 @@ JSON происходит один раз, на границе ODS → DDS, ку
## Движок и наполнение
`MergeTree` без колонки версии: партиция — `order_date` (день заказа
неизменен), ключ сортировки — `order_id`, шардирование распределённой
таблицы — `cityHash64(order_id)`, тем же выражением, что у ODS: это
единственный устойчивый ключ сущности.
`dds.order_rep` — `ReplicatedMergeTree` без колонки версии: партиция —
`order_date` (день заказа неизменен), ключ сортировки — `order_id`.
`dds.order_dist` шардирует по `cityHash64(order_id)`, тем же выражением, что
ODS: это единственный устойчивый ключ сущности.
Идемпотентность держит замена партиции, а не версии. Сбор дня — батч после
прихода слепка: трансформация собирает партицию заново из `ods.order_v` и
атомарно подменяет. Поэтому каждая строка таблицы — ровно один заказ, и
таблица сама служит поверхностью чтения слоя: голый `SELECT`, без `FINAL` и
без обёртки-представления. Пока окно K живо, день «дышит» — статусы заказов
меняются, и партиция дня пересобирается очередным запуском; на выходе из
окна день замерзает.
атомарно подменяет. Поэтому каждая строка физической таблицы — ровно один
заказ, а чтению не нужен `FINAL`. Пока окно K живо, день «дышит» — статусы
заказов меняются, и партиция дня пересобирается очередным запуском; на выходе
из окна день замерзает.
Публичная поверхность — `dds.order_v`: обычное представление с явным списком
деловых и собственных служебных колонок над `dds.order_dist`, без `FINAL`.
Роли объектов и доступ следуют общей [конвенции](../storage.md), «Имена
объектов».
Механика запуска — где собирается партиция и как подменяется на кластере —
сюда не входит: это устройство трансформаций (#134, этап 5).
@@ -86,7 +90,8 @@ JSON происходит один раз, на границе ODS → DDS, ку
- Сверка `dm.purchase_vs_orders_v`: `order_id`, `order_date`, `items_total`,
`status`; соединение — GLOBAL JOIN с обеими сторонами-подзапросами
([исследование соединений](../../research/2026-08-22-distributed-join.md)).
- Сборка `dds.identity_map`: пара `order_id` ↔ `user_id`.
- Сборка карты идентичностей: пара `order_id` ↔ `user_id`, источник —
`dds.order_v`.
## Не входит
@@ -98,11 +103,12 @@ JSON происходит один раз, на границе ODS → DDS, ку
## Отклонённые варианты
- **Представление-контракт вместо физической таблицы.** Рамка стенда —
- **Одно динамическое представление вместо физической таблицы.** Рамка стенда —
показать модель данных, которую хранилище готовит потребителям; урок
«слой — контракт, а не копия» уже закреплён за `dds.event_v`, а разбор
позиций и пересчёт времён при каждом чтении собирали бы модель заново на
лету.
лету. Публичное `dds.order_v` поверх готовой физической модели этому доводу
не противоречит: оно ничего заново не вычисляет.
- **`ReplacingMergeTree(updated_at)` ещё раз.** Повторил бы механику ODS
вторым разом: физически хранил бы устаревшие состояния, вернул бы `FINAL`
и обёртку-представление — а урок версий менти уже отыграл.