Files
clickstream-data-platform/docs/adr/0006-object-naming.md
T
ddadminandClaude Opus 5 abc94ba406 feat(clickhouse): справочники вынесены в зону dic, словарь читает подложку
Зачем: место словаря в 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>
2026-08-20 11:37:26 +03:00

6.5 KiB
Raw Blame History

ADR 0006. Имена объектов хранилища: суффикс вида

Дата: 4 августа 2026 года. Статус: принято.

Решение

Имя объекта в ClickHouse заканчивается тем, что это за объект: _rep — локальная таблица шарда, _distDistributed поверх неё, _kafka — чтец топика, _file — чтец файла, _mv — материализованное представление, _v — обычное представление.

Суффикс _file добавлен 20 августа 2026 года вместе с подложкой под словарём товаров (ADR 0012). Он ровно параллелен _kafka: чтец внешнего источника, по копии на каждой ноде, без репликации и без распределённой пары.

Суффикс носит каждый физический объект, поэтому голого имени у таблицы не существует: запрос к stg.hits_raw даёт ошибку «нет такой таблицы». Единственное исключение — словари: воплощение у них одно, шардировать нечего, и суффикс ничего не различал бы. В документах и разговоре голое имя означает сущность, у которой этих объектов несколько.

Конвенция применена к мастер-спеке тем же решением: stg.kafka_hits стал stg.hits_raw_kafka, dds.v_eventdds.event_v, витрины dm.v_*dm.*_v. Полная таблица суффиксов и следствия для DDL — в доке хранилища.

Почему

Главный довод — как ошибается забытый суффикс. Распространённая конвенция, где голое имя означает локальную таблицу, а распределённая получает _all, ошибается молча: запрос к голому имени вернёт данные одного шарда и никак об этом не скажет. Правило спеки «проверки и контрольные суммы — только по Distributed» такую тишину не переживает: контрольная сумма, посчитанная по половине кластера, выглядит как честное число. При суффиксе вида голого имени нет вовсе, и та же ошибка становится громкой.

Второй довод — что группируется в списке по алфавиту. Суффикс группирует объекты по сущности: все четыре объекта топика hits стоят рядом, потому что различаются хвостом. Префиксный стиль, которым пользовался стенд-предшественник (kafka_*, mv_*, v_*), группирует по технологии, и объекты одной сущности расползаются по алфавиту. В хранилище, где у одной сущности живёт по три-четыре воплощения, полезнее первое. Довод про дерево в клиенте и про ORDER BY name: порядок выдачи SHOW TABLES документация не оговаривает, так что на него здесь опираться нельзя.

Третий — преемственность: _rep и _dist уже используются владельцем в других хранилищах на ClickHouse, и общий словарь между стендами стоит больше, чем локальная стройность.

Отвергнуты, кроме _all: префиксный стиль предшественника — он не покрывает пару локальная/распределённая, для неё префикса просто нет; голое имя как Distributed с суффиксом _local у локальной — привычное имя ведёт в правильную таблицу, но конвенция расходится с другими стендами владельца; раскладка пары по разным базам (stg и stg_dist) — удваивает число баз в каждом слое и разъезжается с таблицей слоёв спеки.

Цена решения — правка принятой спеки задним числом. Имена представлений и витрин переехали с префикса на суффикс, хотя сами объекты спроектированы не полностью и появятся только на этапах 4 и дальше. Размен принят осознанно: конвенция, введённая после того, как по ней написан первый слой, обходится дороже.

Что проверено

Проверять здесь нечем — это соглашение, а не поведение системы. Вместо проверки конвенция прогнана по карте таблиц спеки, раздел 7: суффикс выводится для всех объектов слоёв STG, ODS, DDS и DM, включая пары локальная/распределённая, представления и матвью. Единственным объектом без выводимого суффикса оказался словарь products — отсюда исключение в решении.

Первый прогон был неполным: четыре витрины из восьми остались с префиксом, и заметило это холодное ревью, а не автор. Имена приведены в порядок 5 августа 2026 года. Урок не про имена: «прогнал по документу» — такое же утверждение, как утверждение о поведении системы, и проверять его надо так же.