feat(clickhouse): справочники вынесены в зону dic, словарь читает подложку #107

Merged
ddmitry merged 4 commits from feat/105-dictionary-home into main 2026-08-20 12:26:41 +03:00
Owner

Решает развилку #105: где живут справочники ClickHouse и нужно ли одно правило
для всех.

Решение

Справочные данные — самостоятельная зона dic вне цепочки STG → ODS → DDS → DM.
Читать её вправе любой слой, писать — никто, кроме владельца источника.
dds.products переехал в dic.products.

Веер строился до оценки и включал все варианты, названные в тикете, плюс три,
оспаривающие саму рамку «база выражает принадлежность». Отвергнутые записаны с
причинами в ADR 0012.

Устройство

Словарь читает не файл, а подложку dic.products_file на движке File
намеренное усложнение ради урока: в бою источник словаря приезжает процессом.
Историзацию и представление «последняя загрузка» из промышленного образца не
брали: история каталога — это git.

Источник объявлен формой query, а не table: словарь приводит цену из целых
копеек каталога в Decimal(18, 2), то есть нормализует на входе. Разрыв с
productPrice события, где цена уже в целых рублях, остаётся намеренным — на
нём стоит урок про Float64.

Проверено на собранном заново стенде

  • make clean && make up — зелено; make smoke — 20 проверок, 0 ошибок;
    make lint — чисто.
  • Словарь LOADED, 180 строк; цена Decimal(18, 2), на копейках 188990 → 1889.90.
  • bi читает словарь dictGet-ом со второй ноды, analyst — подложку
    соединением; база dds пуста.
  • Подложка перечитывает файл на каждом запросе, словарь обновляется сам внутри
    окна LIFETIME — замер поймал изменение через 116 секунд.
  • Минимальное право на движок замерено тремя пользователями: достаточно
    GRANT FILE ON *.*, хотя текст отказа называет TABLE ENGINE ON File.

Побочно

Замер вскрыл, что правка файлов настройки ClickHouse не доезжает до живого
контейнера — заведено отдельным багом #106, в этот PR не входит.

Closes #105

Решает развилку #105: где живут справочники ClickHouse и нужно ли одно правило для всех. ## Решение Справочные данные — самостоятельная зона `dic` вне цепочки STG → ODS → DDS → DM. Читать её вправе любой слой, писать — никто, кроме владельца источника. `dds.products` переехал в `dic.products`. Веер строился до оценки и включал все варианты, названные в тикете, плюс три, оспаривающие саму рамку «база выражает принадлежность». Отвергнутые записаны с причинами в [ADR 0012](../src/branch/feat/105-dictionary-home/docs/adr/0012-dictionary-home.md). ## Устройство Словарь читает не файл, а подложку `dic.products_file` на движке `File` — намеренное усложнение ради урока: в бою источник словаря приезжает процессом. Историзацию и представление «последняя загрузка» из промышленного образца не брали: история каталога — это git. Источник объявлен формой `query`, а не `table`: словарь приводит цену из целых копеек каталога в `Decimal(18, 2)`, то есть нормализует на входе. Разрыв с `productPrice` события, где цена уже в целых рублях, остаётся намеренным — на нём стоит урок про `Float64`. ## Проверено на собранном заново стенде - `make clean && make up` — зелено; `make smoke` — 20 проверок, 0 ошибок; `make lint` — чисто. - Словарь `LOADED`, 180 строк; цена `Decimal(18, 2)`, на копейках `188990 → 1889.90`. - `bi` читает словарь `dictGet`-ом со второй ноды, `analyst` — подложку соединением; база `dds` пуста. - Подложка перечитывает файл на каждом запросе, словарь обновляется сам внутри окна `LIFETIME` — замер поймал изменение через 116 секунд. - Минимальное право на движок замерено тремя пользователями: достаточно `GRANT FILE ON *.*`, хотя текст отказа называет `TABLE ENGINE ON File`. ## Побочно Замер вскрыл, что правка файлов настройки ClickHouse не доезжает до живого контейнера — заведено отдельным багом #106, в этот PR не входит. Closes #105
ddmitry added 1 commit 2026-08-20 11:38:04 +03:00
Зачем: место словаря в dds было унаследовано от первого объекта, а не решено.
Справочник читают несколько слоёв, а производит его в хранилище ни один —
прописка внутри одного из потребителей приписывала DDS владение, которого у
него нет.

Что: заведена база dic вне цепочки STG → ODS → DDS → DM, dds.products переехал
в dic.products. Под словарём появилась подложка dic.products_file на движке
File — намеренное усложнение ради урока: в бою источник словаря приезжает
процессом, а не лежит файлом у сервера. Источник объявлен формой query и
приводит цену из целых копеек каталога в Decimal(18, 2), как у денег бэкенда.
Обновление — окном LIFETIME(MIN 60 MAX 90) вместо ручной перезагрузки, ценой
заявленной неатомарности между нодами. У словаря свой беспарольный
пользователь dict с единственным правом на чтение dic. Суффикс _file добавлен
в конвенцию имён ADR 0006. Решение, отвергнутые варианты и условия пересмотра
— ADR 0012.

Проверка: make clean && make up на собранном заново стенде — зелено, make smoke
20 проверок и 0 ошибок, make lint чисто. Словарь LOADED со 180 строками, цена
Decimal(18, 2) и точна на копейках: 188990 → 1889.90. Пользователь bi читает
словарь dictGet-ом со второй ноды, analyst — подложку соединением, база dds
пуста. Минимальное право на движок замерено тремя пользователями: достаточно
GRANT FILE ON *.*, хотя отказ называет TABLE ENGINE ON File.

Closes #105

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ddmitry added 1 commit 2026-08-20 11:42:34 +03:00
Зачем: каждое утверждение о словаре было записано трижды — в доке хранилища, в
комментариях DDL и в ADR 0012. Правка поведения стоила бы трёх согласованных
правок, а расхождение между копиями обнаружилось бы не сразу. Дока хранилища —
карта, а не пересказ реализации.

Что: раздел «Справочники» сведён к своему уровню — правило принадлежности зоны,
топология на кластере, единицы денег и указатели. Механика (движок, форма пути,
пользователь, окно обновления) осталась только в sql/ddl/05-dic-catalog.sql,
рядом с кодом, который она объясняет. Блок «Что проверено» отправлен к замерам
ADR 0012 вместо их пересказа — так же, как он уже поступает с ADR 0005.

Проверка: минус 30 строк; ссылок на убранный подзаголовок в репозитории нет,
три относительные ссылки нового текста разрешаются в существующие файлы.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ddmitry added 1 commit 2026-08-20 11:47:29 +03:00
Зачем: горячее ревью поймало ошибку в трёх местах сразу. Было записано, что
после правки каталога ноды расходятся до тридцати секунд — число взято из
ширины окна LIFETIME(MIN 60 MAX 90). Ширина тут ни при чём: каждая нода ждёт
правки от нуля до верхней границы окна, фазы у них независимы, поэтому
расходиться они могут почти на все полторы минуты.

Что: исправлены ADR 0012, опорная точка мастер-спеки и комментарий DDL. Заодно
уточнено, что LIFETIME(0) неатомарность не предотвращал, а сжимал до разброса
исполнения SYSTEM RELOAD DICTIONARY ON CLUSTER, и что витрина выручки пока
спроектирована, а не построена.

Проверка: рассуждением, замером не подтверждалось — прежнее число тоже было
выведено, а не измерено. Замер в ADR (116 секунд на окне MIN 60 MAX 120)
относится к другому утверждению: что словарь обновляется сам.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ddmitry added 1 commit 2026-08-20 12:10:09 +03:00
Зачем: ревью в три линии нашло настоящий дефект. Девятая проверка кластера
звала dictGet('dds.products', …) — объекта после переноса не существует, и
make check-clickhouse падал. Промах вырос из недосчёта: упоминания dds.products
я искал с фильтром по расширениям, .sh туда не попал, и в ADR уехало «четыре
упоминания» вместо семи.

Что: проверка переведена на dic.products и сверяет цену, умножив её обратно на
сто, — так утверждается ещё и точность приведения к Decimal. Раздел 3
мастер-спеки и список пользователей README догнали перенос: оба описывали
отменённое устройство. В ADR 0012 добавлено условие пересмотра для дома — для
него его не было, хотя ради дома тикет и заводился; недосчёт записан в
«Что проверено» как урок. Разнобой обозначений сведён: карта таблиц в доке
хранилища перешла на имена баз строчными, таблица мастер-спеки — на заголовок
«Где», зону всюду зовут зоной, а не слоем. Термин «Справочник» переписан без
метафоры и уложен в формат глоссария. Вычтено лишнее: комментарии DDL
сократились вдвое, из ADR 0006 и 0007 убраны самооправдание и дублирующие
абзацы, отраслевой образец получил честную оговорку о непроверяемости.

Проверка: make config-test, make lint, make smoke и make check-clickhouse —
все зелёные, десять проверок кластера из десяти.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ddmitry merged commit 7b89ccb529 into main 2026-08-20 12:26:41 +03:00
ddmitry deleted branch feat/105-dictionary-home 2026-08-20 12:26:42 +03:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ddmitry/clickstream-data-platform#107