DP-600: implementar relações many-to-many em modelos semânticos
Vou ensinar como implementar correctamente relações many-to-many (M:N) em modelos semânticos no contexto do exame DP-600 e na prática profissional. Esta competência é frequente em modelos reais com granularidades diferentes e é importante para garantir resultados correctos e desempenho aceitável.
O que precisas de saber
Uma relação many-to-many (M:N) ocorre quando várias linhas numa tabela A se relacionam com várias linhas numa tabela B. Em modelos relacionais simples (star schema) evitamos isto, mas dados do mundo real (ex.: produtos com múltiplas etiquetas, clientes em várias regiões, eventos com múltiplos participantes) geram M:N. No contexto de modelos semânticos (Power BI / Fabric), lidar mal com M:N provoca contagens erradas, duplicações em agregações e problemas de desempenho.
Há duas abordagens comuns:
- Bridge table (tabela de ligação) normalizada: uma tabela de factos que expressa a relação entre as duas entidades.
- Modelo com tabela de relação e cardinalidade configurada no modelo semântico usando propriedades como "Many-to-many (single direction / both directions)" e, ocasionalmente, colunas de contagem distinta para controlar agregações.
Exemplo prático: temos uma tabela Product e uma tabela Tag. Um produto pode ter várias tags e uma tag pode aplicar-se a vários produtos. Se juntarmos Product e Tag directamente sem uma tabela de ligação, vamos duplicar métricas (ex.: Sales) por cada tag associada.
Como funciona
Passos conceptuais para implementar correctamente um cenário M:N usando uma bridge table:
- Identificar as tabelas envolvidas e a natureza da relação (A ⇄ B).
- Criar uma tabela de ligação (Bridge) que contenha pares de chaves: ProductID, TagID. Esta tabela não deve conter valores de métricas factuais que seriam duplicados.
- Estabelecer relações 1:N entre Product → Bridge (1 lado é Product) e Tag → Bridge (1 lado é Tag). No modelo semântico, ambas as relações devem ser com cardinalidade one-to-many (1:N), com a Bridge do lado muitos.
- Configurar a direccionalidade do filtro: geralmente usa-se Single direction das dimensões para a Bridge ou Both directions quando preciso propagar filtros através da bridge para factos, mas Both directions pode afectar desempenho e introduzir ambiguidade. Prefere Single e medidas explícitas quando possível.
- Escrever medidas DAX que evitem duplicação: quando agregas factos através da bridge, usar funções como DISTINCT, SUMX sobre valores agregados por chave, ou medidas que calculem sobre a tabela de factos original e depois relacionem com a bridge sem duplicar.
-- Exemplo DAX (padrão) para somar Sales por Tag sem duplicar quando Product tem várias tags
Sales by Tag =
VAR ProductsForTag =
DISTINCT( Bridge[ProductID] )
RETURN
CALCULATE(
SUM( Sales[SalesAmount] ),
KEEPFILTERS( ProductsForTag )
)
Alternativa com SUMX para garantir um somatório único por produto:
Sales by Tag 2 =
SUMX(
VALUES( Bridge[ProductID] ),
CALCULATE( SUM( Sales[SalesAmount] ) )
)
Na prática
Exemplo passo-a-passo num ambiente Fabric / Power BI Desktop:
- No Data Factory / Power Query, criar a Bridge table com pares ProductID-TagID. Não importes colunas desnecessárias que aumentem cardinalidade.
- No Model view, ligar Product[ProductID] → Bridge[ProductID] (1 → *), e Tag[TagID] → Bridge[TagID] (1 → *).
- Definir ambas as relações como Single direction por defeito. Só usar Both directions se uma necessidade clara de filtragem bidireccional existir (ex.: slicers que precisam cruzar ambas as dimensões através da Bridge).
- Criar medidas no espaço de medidas (model) que usem VALUES/DISTINCT para evitar duplicação. Testar com cartões e tabelas para confirmar que as somas correspondem ao total esperado.
- Monitorizar cardinalidades e compressão: no Fabric / Power BI, tabelas com alta cardinalidade na bridge aumentam o modelo; avaliar se a bridge pode ser reduzida (por exemplo, usando inteiros menores, removendo colunas desnecessárias, ou agregando).
Erros comuns
- Duplicação de factos ao agregar sem usar DISTINCT/VALUES ou sem uma bridge normalizada — causa totais inflacionados.
- Usar Both directions de forma automática e sem avaliar — pode resolver filtros mas introduz loops de relações, ambiguidades e degradar desempenho.
- Colocar métricas na bridge (ex.: SalesAmount) em vez de mantê-las na tabela de factos — promove maior cardinalidade e dificulta cálculos correctos.
Como praticar
Pratica com um dataset que contenha relações M:N (por exemplo: Products, Tags, Sales). Implementa a bridge e cria medidas que confirmem os totais. Para avaliação oficial, utiliza o Practice Assessment OFICIAL da Microsoft (gratuito) e segue a study guide da Microsoft (gratuita) para DP-600. Esses recursos são os únicos que reproduzem o formato e o tipo de questões do exame; usa-os para validar conhecimentos e identificar lacunas.
Em resumo
- Usa uma bridge table para normalizar relações M:N e evita duplicação de factos.
- Prefere Single direction nas relações e escreve medidas DAX com DISTINCT/VALUES ou SUMX para somatórios correctos.
- Avalia cardinalidade e desempenho: reduz colunas e tipos desnecessários na bridge.
- Pratica com datasets reais e valida com o Practice Assessment oficial e a study guide da Microsoft (ambos gratuitos).