Урок 05 · 9 мин чтения

Таблица-мост вместо «многие ко многим»

Как заменить капризную m2m-связь двумя связями «один ко многим» через таблицу-мост — и где включать двунаправленность.

«Многие ко многим» — частая реальность. Один товар попадает в несколько акций, а в акции участвуют много товаров. Один клиент платит с нескольких счетов, а со счёта платят несколько клиентов. Power BI умеет физическую m2m-связь напрямую, но она капризна: неоднозначные пути, сюрпризы с итогами, обязательная двунаправленность. Чище — таблица-мост.

Идея моста

Между двумя таблицами с отношением «многие ко многим» ставят третью — мост (bridge), где каждая пара встречается по одной строке. Тогда вместо одной m2m получаются две нормальные связи «один ко многим», направленные в мост:

   Товары (1) ──► ТоварТег (∞)   ◄── (1) Теги
                  [мост]

ТоварТег — это просто список пар «КодТовара ↔ Тег»: товар «Молоко» — теги «новинка», «эко»; товар «Чипсы» — тег «акция». Каждая пара уникальна. Слева мост связан с Товары, справа — с Теги, обе связи «один ко многим» со стороны моста.

Что мы выиграли

Две предсказуемые связи «один ко многим» вместо одной хрупкой m2m. Мост явно виден в модели, его легко проверить и почистить от дублей. Это стандартный, надёжный приём.

Где живёт двунаправленность

Вот ключевой нюанс. По умолчанию фильтр течёт от измерения к мосту, но не дальше. Выбрали тег «акция» → отфильтровался мост → а до Товары (и до Продажи) фильтр сам не дойдёт, потому что в мост связь входит, а не выходит.

Чтобы выбор тега фильтровал продажи, нужно пропустить фильтр через мост к Товары. Два способа:

1. Двунаправленная связь — только на ребре Товары ↔ ТоварТег. Делаем эту одну связь двунаправленной (cross filter both). Теперь тег → мост → товары → продажи. Связь Теги → мост остаётся однонаправленной.

2. CROSSFILTER в мере — точечно и безопасно. Не трогаем модель, включаем сквозной фильтр только там, где нужно:

Выручка по тегу =
CALCULATE (
    [Выручка],
    CROSSFILTER ( Товары[КодТовара], ТоварТег[КодТовара], BOTH )
)
Двунаправленность — точечно

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

Мост между двумя фактами

Тот же приём связывает две таблицы фактов на разной грануляции через общее измерение-мост. Бюджет по категории и продажи по товару связывают не напрямую, а через общий справочник (категория/товар) — он и работает мостом. Если общего справочника нет, его создают (DISTINCT/VALUES по ключу) специально как мост.

Когда мост, когда TREATAS

В прошлом уроке мы связывали таблицы виртуально через TREATAS. Когда что:

  • Мост — когда связь нужна постоянно, грануляция позволяет, и важна скорость (физические связи оптимизированы движком). Это «production»-вариант для m2m.
  • TREATAS — когда физическую связь сделать нельзя или она ведёт себя плохо; считается на лету, дороже на больших данных.
Проверьте мост на дубли

Мост обязан содержать уникальные пары. Дубли строк раздувают результат (выручка «задвоится»). Если строите мост из данных — гоните через DISTINCT/SUMMARIZE, а не копируйте «как есть».

Что дальше

Со связями почти закончили — физические, неактивные, виртуальные и мост. Остался выбор режима хранения: когда данные не импортируют, а оставляют в источнике. Дальше — композитные модели и DirectQuery. Следующий урок.

Товар может иметь много тегов, тег — у многих товаров. Как смоделировать это надёжно?
Мост с уникальными парами «товар ↔ тег» превращает m2m в две предсказуемые связи «один ко многим». Чтобы выбор тега фильтровал продажи, ребро «Товары ↔ мост» делают двунаправленным или включают CROSSFILTER(…, BOTH) в мере.
Прогресс сохраняется в вашем браузере.
§ Power BI под ключ

Нужно внедрить
это в компании?

Соберём DWH, модель и дашборды под ваши данные. Бесплатная консультация — 30 минут.

Телефон+7 918 042 34 43