Página conceitual sobre o que acontece quando duas tabelas se ligam: a cardinalidade (quantas linhas de cada lado), a direção de filtro (para onde o recorte se propaga) e a proteção anti-fan-out (por que o produto às vezes se recusa a somar). A configuração passo a passo está no modelo semântico; aqui explicamos por que cada opção importa.
Exemplos com o workspace sintético Comércio Aurora Ltda (aurora), tabelas
vendas, produtos, clientes, filiais, calendario.
Maturidade
O motor de relações, cardinalidade, caminho de join e detecção de
ciclo/ambiguidade é GA-candidato (coberto por contrato de relações e conjunto de testes de referência). Execução no datalake de produção é NÃO MEDIDO.
O que é um relacionamento#
Um relacionamento diz que uma coluna de uma tabela aponta para a coluna
identificadora de outra: vendas.produto_id → produtos.id. Ao montar o SQL, o
gerador encontra o caminho de join percorrendo o grafo do modelo e emite
LEFT JOIN sempre no sentido fato → dimensão.
Você desenha as ligações arrastando no diagrama visual do editor. Cada linha do diagrama carrega duas decisões: cardinalidade e direção de filtro.
Onde fica o diagrama
Em edição, clique em Relacionamentos na barra do editor (ou em Dados → Diagrama). O canvas dá lugar ao diagrama das tabelas do modelo, e a faixa mostra:
| Grupo | Botão | O que faz |
|---|---|---|
| Modelo | Sugerir relações | Sugere ligações pelos nomes das colunas; você aceita uma a uma |
| Modelo | Organizar | Arruma os cartões das tabelas em grade |
| Dados | Exibir dados | Mostra uma amostra de 100 linhas das tabelas do modelo |
| Zoom | Menos · Ajustar · Mais | Afasta, volta a 100% e centraliza, ou aproxima |
No próprio diagrama, uma linha marcada avisa quando há risco: amostra que viola a cardinalidade declarada, relação N-N que pede uma tabela ponte, ou dois caminhos empatados (o gerador recusa a consulta). Ao selecionar duas tabelas, o diagrama destaca o caminho real que o gerador usa entre elas.
Cardinalidade: qual lado é "um" e qual é "muitos"#
| Cardinalidade | Significado | Exemplo Aurora |
|---|---|---|
1-N / N-1 | Um do lado dimensão, muitos do lado fato (o caso normal). | Um produto tem muitas vendas. |
1-1 | Uma linha de cada lado. | filiais ↔ uma tabela de metadados por filial. |
N-N | Muitos dos dois lados — exige tabela-ponte. | produtos ↔ promocoes via produto_promocao. |
A cardinalidade não é decorativa: ela protege seus números.
Proteção anti-fan-out (por que a soma às vezes é recusada)
Quando um join 1-N multiplica linhas, uma soma sobre o lado "um" seria
contada várias vezes. Exemplo: filiais tem uma coluna meta; se você juntar
filiais a vendas (uma filial, muitas vendas) e somar filiais.meta, a meta é
contada uma vez por venda — inflada.
O ingestia.bi detecta esse estouro de linhas e bloqueia a agregação afetada, com uma mensagem didática, em vez de entregar o total errado em silêncio. É o que o Power BI resolve pedindo modelagem correta; aqui é guarda automática consciente do grão.
Warning
Se uma soma aparecer bloqueada, o problema quase sempre é de grão: você está somando uma medida do lado "um" através de um join que a duplica. Coloque a medida no fato de grão correto, ou some do lado certo da relação.
Direção de filtro#
Por padrão, o filtro flui do UM para o MUITOS (dimensão → fato): escolher uma
categoria em produtos recorta as vendas daquela categoria. É o comportamento
que você quase sempre quer.
Bidirecional (opt-in)
crossFilter: "both" liga a propagação nos dois sentidos de uma relação
específica. Útil quando filtrar o fato precisa também recortar a dimensão — por
exemplo, mostrar só os produtos que tiveram venda no período filtrado.
Detalhes importantes:
- O grafo de join é não-direcionado (o SQL físico não muda ao ligar "both"); o que muda é o grafo de filtro.
- O modelo detecta ciclo e ambiguidade de propagação e recusa um modelo cujo significado ficaria indefinido — nunca gera SQL ambíguo calado.
- É opt-in por relação: um modelo todo "single" não sofre nenhuma mudança.
Papéis de relação (role-playing)#
Quando o fato tem várias datas (pedido, entrega, pagamento), você liga a
mesma dimensão calendario várias vezes, cada ligação com um papel
nomeado. Uma relação fica ativa, as outras inativas; o visual escolhe o
papel ("Data do Pedido" × "Data de Entrega") sem reescrever fórmula. Papéis do
mesmo par de tabelas formam um grupo detectado automaticamente.
Exemplo Aurora: calendario ligada a vendas por data_pedido (ativa),
data_entrega e data_pagamento (inativas). No visual, trocar de "Data do Pedido"
para "Data de Entrega" muda o eixo sem tocar nas medidas.
Relação N-N por ponte#
Uma relação muitos-para-muitos precisa de uma tabela-ponte com chave para as
duas pontas. Ex.: produtos ↔ promocoes via produto_promocao. Ao cruzar
A → ponte → B, a medida do lado oposto é deduplicada (a ponte é reduzida a
pares distintos antes de somar), evitando dupla contagem. Uma medida que vive na
própria ponte soma direto, porque o grão dela é a ponte.
Sem ponte declarada, um N-N é tratado como ambíguo e recusado — de novo, o produto prefere avisar a errar.
Como escolher, na prática#
- Dúvida? Deixe
1-Ndo fato para a dimensão, direção single. Cobre a esmagadora maioria dos casos. - Ligue bidirecional só quando precisar recortar a dimensão pelo fato, e confirme que o editor não acusou ambiguidade.
- Use papéis quando houver várias datas/chaves para a mesma dimensão.
- Use ponte para qualquer N-N; nunca force um N-N sem ela.
Limites e ressalvas#
- O join físico é sempre fato → dimensão; não há relações "virtuais" em memória.
- Teto de papéis por modelo (
MAX_RELATION_ROLES). - A prova é do motor (contrato de relações + conjunto de testes de referência); o desempenho do
join no datalake real é
NÃO MEDIDO.
Relacionados#
- Modelo semântico
- Conceitos de modelagem dimensional
- Contexto de linha e de filtro
- Tutorial: modelo estrela
- As faixas do editor
Última revisão: 2026-10-03.