Dimensions (дименшены)
Дименшен (разрез) - это способ группировать и фильтровать метрики, а заодно расшифровывать числовые идентификаторы в человекочитаемые значения в отчётах по AB-тестам. Один дименшен заводят один раз и переиспользуют для тысяч метрик.
- Дименшен задаёт разрез метрики: по нему метрику считают не в тотале, а с условием - например
category = «Личные вещи». - Одновременно дименшен работает как справочник: связывает числовой id значения с человекочитаемым названием, чтобы в отчёте показывать «Москва», а не
213. - Конфигурация дименшена - строка в файле
dimensions/dimensions.yamlплюс, для небулевых ди меншенов, SQL-справочник значений вdimensions/sql/<имя>.sql. - Список значений наполняет ежечасный фоновый процесс, а не сам мёрдж: после правки SQL значения появляются на ближайшем часовом прогоне.
- Аналитик всегда оперирует расшифрованными значениями, а не идентификаторами, - даже если в данных дименшен хранится числовым id.
Что такое дименшен
У дименшена две роли, и обе нужны одновременно.
Разрез метрики. Разрез (он же слайс, breakdown) - это условие, которое накладывают на метрику. Одну и ту же метрику buyers можно посчитать в тотале или с условием по дименшену. В наборе разрезов условие задают списком значений по дименшенам, объединённых логическим И: vertical IN (...) AND category IN (...). Наборы разрезов и пресеты описаны на странице Списки метрик.
Справочник значений. Дименшен хранит список допустимых значений и маппинг между идентификатором и названием. Например, region_id = 213 расшифровывается в region = «Москва». Этот список используют и для валидации разрезов в конфигах экспериментов, и для подстановки понятных названий в отчёты.
Дименшен бывает трёх форм - они различаются типом значений и наличием SQL-справочника:
| Форма | Флаг в yaml | Значения | SQL-справочник |
|---|---|---|---|
| Обычный | нет | строковые | обязателен |
| С идентификатором | has_id: true | числовой id + расшифровка (value_id -> value) | обязателен |
| Булев | is_bool: true | true / false | не нужен и запрещён |
Дименшены можно выстроить в иерархию через поле parent - например category -> logical_category -> vertical. Иерархия задаёт порядок и связь значений «ребёнок -> родитель» (подробнее в разделе Как дименшен виден аналитику).
Почему это важно
- Понятные отчёты. Без справочника отчёт показывал бы сырые id вроде
213. Дименшен сhas_idподставляет вместо них названия. - Цели на срезе аудитории. Цели эксперимента часто ставят на метрику с разрезом, а не в тотале: не «все покупатели», а «покупатели в
vertical = «Транспорт»». - Переиспользование. Один дименшен подключается к тысячам метрик, поэтому новый дименшен заводят редко и аккуратно.
Как дименшен устроен в Trisigma
Два файла конфигурации
Дименшен описывают двумя артефактами репозитория метрик: метаданными в общем yaml-файле и SQL-справочником значений.
dimensions/dimensions.yaml - один общий файл, по строке на дименшен. Здесь метаданные: тип, описание, иерархия.
# dimensions/dimensions.yaml
region:
has_id: true
description: "Регион"
slug: reg
parent: country
Обязателен только ключ-имя дименшена. Остальные поля опциональны:
| Поле | Ти п | По умолчанию | Назначение |
|---|---|---|---|
has_id | bool | false | Значения - числовые id. Физическая колонка источника становится <имя>_id |
is_bool | bool | false | Булев дименшен со значениями true / false, без SQL |
parent | строка | нет | Имя родительского дименшена для иерархии |
description | строка | имя дименшена | Описание |
slug | строка | имя дименшена | Краткое имя для отображения в отчёте |
dimensions/sql/<имя>.sql - отдельный SQL-файл на каждый небулев дименшен. Его содержимое (values_sql) возвращает справочник значений. Колонки переименовывают в стандартные имена - платформа распознаёт только их:
-- dimensions/sql/region.sql
SELECT
name AS value, -- человекочитаемое значение
region_id AS value_id -- числовой id (обязателен при has_id)
FROM dds.h_region
Колонки SQL-справочника
Набор колонок строго фиксирован. Обязательна только value; остальные подключают по мере необходимости:
| Колонка | Тип | Когда нужна | Назначение |
|---|---|---|---|
value | строка | всегда | Человекочитаемое значение разреза |
value_id | число | при has_id | Внутренний числовой id значения |
value_ext_id | число | опционально | Внешний id; имеет приоритет над value_id |
parent_dimension | строка | для иерархии | Имя родительского дименшена |
parent_value | строка | для иерархии | Значение родителя |
parent_value_id | число | для иерархии | Id значения родителя |
is_active | bool | опционально | Активность значения (по умолчанию активно) |
Возвращать все колонки не нужно: недостающие платформа подставляет сама (NULL, а для is_active - true), а value всегда приводит к строке. Колонка вне этого набора или с неверным типом останавливает валидацию.
Имена колонок результата обязаны совпадать со стандартными (value, value_id и так далее). Любые другие имена платформа не распознаёт.
Как наполняется справочник значений
Список допустимых значений хранится в справочнике на стороне платформы, а не вычитывается из SQL на лету. Наполняет его фоновый процесс:
- Раз в час процесс берёт активные дименшены и исполняет их
values_sqlв Trino. - Результат дифференциально записывается в справочник: новые значения добавляются, пропавшие из источника помечаются неактивными (а не удаляются), существующие обновляются.
- Булев дименшен в Trino не ходит - его значения
true/falseзашиты.
Отдельный ежедневный процесс заранее обновляет сами таблицы-источники в Trino, из которых потом чит аются значения.
После мёрджа нового или изменённого SQL значения попадают в справочник не мгновенно, а на ближайшем часовом прогоне. До него разрез по новым значениям валидацию не пройдёт.
Валидация значений в разрезах
Когда аналитик собирает набор разрезов, платформа сверяет каждое значение со справочником (учитываются только активные значения):
- значения нет в справочнике - ошибка
Неизвестное значение <X> для дименшена <Y>; - самого дименшена нет в конфиге - ошибка
Неизвестный дименшен: <Y>.
Эти две ошибки различают две ситуации: в первой дименшен распознан, а его справочник значений пуст или неполон; во второй платформа не знает самого дименшена.
Создание дименшена
Дименшен живёт в репозитории метрик, поэтому изменения проводят обычным git-процессом: ветка -> правки файлов -> коммит -> PR -> мёрдж. Файлы правят вручную и ведут через git напрямую либо через CLI Trisigma - она оборачивает git-шаги (task / save / publish) и добавляет локальную валидацию и сборку. Команды CLI описаны в разделе Командный режим.
- Заведите ветку в репозитории метрик.
- Если в источнике нет нужного поля - добавьте колонку в
sources/или в обогащение вenrichments/. - Опишите дименшен строкой в
dimensions/dimensions.yaml. - Создайте справочник
dimensions/sql/<имя>.sql(колонкаvalueобязательна). - Проверьте изменения: локально через CLI (
trisigma sl validate,trisigma sl compile --metrics <метрика> --dimensions <имя>) или серверной валидацией - она прогоняется на PR автоматически и перезапускается командойrun testsв комментарии PR. - Откройте PR, дождитесь серверной валидации, затем смёрджите его командой
run mergeв комментарии PR. - Дождитесь часового прогона - он наполнит справочник значений.
Минимальный пример - дименшен platform с расшифровкой id:
# dimensions/dimensions.yaml
platform:
has_id: true
description: "Платформа"
-- dimensions/sql/platform.sql
SELECT
name AS value,
platform_id AS value_id
FROM dds.h_platform
Полезные команды CLI для дименшенов:
| Команда | Что делает |
|---|---|
trisigma sl list-dimensions | Таблица всех дименшенов: имя, описание, тип |
trisigma sl validate | Локальная проверка репозитория метрик (код выхода 0 / 1) |
trisigma sl compile --metrics <m> --dimensions <d> | Пробная сборка метрики с разрезом |
Ограничения и правила валидации
- Имя. Только латиница, цифры,
_и., начинается с буквы или_. Имя не может заканчиваться на_id- этот суффикс зарезервирован для физической колонки-идентификатора. has_id- только для числовых id. Для строкового поля флаг ставить нельзя, валидация не пройдёт.- Булев дименшен - без SQL. У
is_bool: trueне должно быть файла вdimensions/sql/. Небулев дименшен, наоборот, обязан иметь SQL (исключение - старые дименшены, заведённые до этого правила). - Колонки SQL - только из стандартного набора, с правильными типами;
valueобязательна. - Наполнение идёт пачками. Дименшены с одинаковым набором колонок платформа склеивает в один Trino-запрос (до 25 в пачке) через
UNION. Поэтому ошибка в одномvalues_sqlроняет наполнение и других дименшенов из той же пачки.
Список значений: VALUES, а не UNION ALL
Если справочник задаётся явным списком значений, а не выборкой из таблицы, перечисляйте их одним блоком VALUES:
-- dimensions/sql/my_dimension.sql
SELECT value
FROM (VALUES
('Группа A'),
('Группа B'),
('other')
) AS t(value)
На длинном списке (сотни значений) цепочка SELECT ... UNION ALL SELECT ... раздувает план запроса: каждая ветка добавляет стадию, и Trino отклоняет слишком большой план. Наполнение падает для всей пачки дименшенов, которые склеиваются в один запрос, и в наборе разрезов появляется Неизвестное значение. Блок VALUES сворачивается в один узел плана и этой проблемы лишён.
Если значения живут в данных, берите их выборкой вместо ручного списка:
SELECT DISTINCT some_column AS value
FROM <источник>
WHERE some_column IS NOT NULL
Частые ошибки
| Симптом | Причина | Что делать |
|---|---|---|
Неизвестное значение <X> для дименшена <Y> (дименшен при этом распознан) | Справочник не наполнился: values_sql написан через UNION ALL, либо ещё не прошёл часовой прогон, либо значение неактивно или записано иначе | Переписать список на VALUES; дождаться прогона; сверить значение буква-в-букву |
Неизвестный дименшен: <Y> | Дименшена нет в dimensions/dimensions.yaml или конфиг ещё не доехал | Проверить запись в yaml |
Ошибка валидации на has_id | has_id: true поставлен строковому дименшену | Убрать has_id |
Non-boolean dimension ... should have sql | У небулева дименшена нет файла в dimensions/sql/ | Добавить SQL-справочник |
Как дименшен виден аналитику
- Слайсы - по расшифрованным значениям. Разрез всегда конфигурируют по человекочитаемым значениям, никогда по числовым id, даже если в данных дименшен хранится как
<имя>_id. - Краткое имя в отчёте. В AB-отчёте дименшен подписывается своим
slug(напримерlogical_categoryпоказывается какlogcat). - Иерархический путь. У иерархических дименшенов значение показывается путём от корня:
USA > NY > NYC. Связь задают колонкиparent_dimension,parent_value,parent_value_idв справочнике. - Тотал по разрезу. Значение
Anyозначает «без разреза по этому дименшену» - то есть тотал по данному типу.
Итог и сл едующие шаги
Дименшен - это и разрез метрики, и справочник id -> значение. Его описывают строкой в dimensions/dimensions.yaml и (для небулевых) SQL-справочником в dimensions/sql/<имя>.sql; значения наполняет ежечасный фоновый процесс.
- Наборы разрезов и пресеты - Списки метрик.
- Источники полей для дименшенов - Sources и Enrichments.
- Использование разрезов в метриках - Metrics.
- Практический сценарий заведения - Workflow.
- Команды CLI - Командный режим.