Selo de estado:
Preview(teto atual do produto) · Curso ACD-310 — Modelo semântico e modelagem dimensional · Aula 4 de 10 · Atualizado em 2026-10-04.
Objetivo#
Ao final desta aula você vai prever, antes de rodar a consulta, quando um join vai duplicar linhas e inflar uma soma — e entender por que o produto recusa a agregação nesses casos.
Vídeo#
Identificador no manifesto: acd-310-04-relacoes-cardinalidade-fan-out · duração-alvo 8 min · tela do produto: /dashboards.
Roteiro:
00:00–01:20— As três cardinalidades:1-N/N-1,1-1,N-N· tela:/dashboards/[id](diagrama do modelo, relaçãovendas→produtos)01:20–03:00— Por que a cardinalidade não é decorativa: o join físico sempre vai fato → dimensão · tela:/dashboards/[id](propriedades da relação)03:00–05:30— Fan-out na prática: somarfiliais.metasobre o join comvendase ver o bloqueio · tela:/dashboards/[id](visual novo, mensagem de recusa)05:30–07:00— Lendo a mensagem didática e corrigindo: mover a medida para o fato certo · tela:/dashboards/[id](medida corrigida, visual voltando a funcionar)07:00–08:00— N-N sem ponte: por que é tratado como ambíguo e recusado · tela:/dashboards/[id](tentativa de ligarprodutos↔promocoesdireto)
Conteúdo#
As aulas 2 e 3 trataram cardinalidade e direção como um detalhe técnico do diagrama. Esta aula mostra por que ela tem efeito real sobre o número final — e por que, às vezes, o ingestia.bi se recusa a somar algo em vez de arriscar um total errado. A referência completa é Relacionamentos, cardinalidade e direção de filtro.
As três cardinalidades
| Cardinalidade | Significado | Exemplo Aurora |
|---|---|---|
1-N / N-1 | Um do lado dimensão, muitos do lado fato — o caso normal. | Um produto tem muitas linhas em vendas. |
1-1 | Uma linha de cada lado. | filiais ↔ uma tabela de metadados por filial (quando existir). |
N-N | Muitos dos dois lados — exige tabela-ponte (aula 5). | produtos ↔ promocoes, via produto_promocao. |
A cardinalidade não é decorativa: ela é o que o gerador de SQL usa para decidir se uma soma é segura.
Por que a soma às vezes é recusada: fan-out
Quando um join 1-N multiplica linhas, uma soma sobre o lado "um" seria contada mais de uma vez. O exemplo clássico, direto do Aurora: filiais tem uma coluna meta. Se você juntar filiais a vendas (uma filial, muitas vendas) e tentar SOMA(meta) sobre esse join, a meta da filial é contada uma vez por venda daquela filial — um número várias vezes maior que o real.
O ingestia.bi detecta esse estouro de linhas (as funções internas são hopFansOut/joinDuplicatesRows) e bloqueia a agregação afetada, com uma mensagem didática, em vez de entregar o total errado em silêncio. É a mesma situação que o Power BI resolve pedindo para você modelar corretamente antes; aqui é uma guarda automática, consciente do grão que você definiu na aula 2.
Aviso
Se uma soma aparecer bloqueada no editor, o problema é quase sempre de grão: você está somando uma medida do lado "um" através de um join que a duplica. A correção normal é colocar a medida no fato de grão correto, ou somar do lado certo da relação — nunca forçar o número a aparecer ignorando o aviso.
Com dados sintéticos: se filiais tem 2 linhas e vendas tem 6 linhas ligadas a elas por cidade, somar filiais.meta direto sobre esse join contaria a meta de cada filial 3 vezes (uma por venda) — exatamente o caso que a proteção bloqueia.
Direção de filtro (prévia da aula 5)
Além da cardinalidade, cada relação tem uma direção de filtro. Por padrão, o filtro flui do lado "um" para o lado "muitos" — escolher uma categoria em produtos recorta as vendas daquela categoria, nunca o contrário. A aula 5 detalha o modo bidirecional opt-in (crossFilter: "both"), que liga a propagação nos dois sentidos quando você realmente precisa.
N-N sem ponte: por que é recusado
Uma relação muitos-para-muitos — por exemplo, produtos ↔ promocoes, onde um produto pode estar em várias promoções e uma promoção pode ter vários produtos — não pode ser ligada como se fosse N-1. Sem uma tabela-ponte explícita (como produto_promocao), o significado da relação fica indefinido, e o modelo trata isso como ambíguo e recusa a ligação — em vez de gerar um SQL que pareceria funcionar, mas contaria errado. A solução com tabela-ponte é o tema da aula 5.
Como isso aparece no produto
No editor do dashboard (/dashboards/[id]), cada relação do diagrama tem uma propriedade de cardinalidade (1-1 | 1-N | N-1 | N-N) e de direção de filtro. O gerador de SQL encontra o caminho de join percorrendo esse grafo e emite sempre LEFT JOIN no sentido fato → dimensão. Quando uma agregação cruzaria um caminho que duplica linhas, o editor mostra a recusa no próprio visual, com uma explicação em português — não um erro técnico de banco de dados.
Erros comuns
- Ignorar o aviso e tentar "forçar" o número. Reescrever a fórmula para contornar o bloqueio sem entender a causa quase sempre reintroduz a duplicação de outro jeito.
- Confundir o bloqueio com um bug. Ele é uma proteção — o produto prefere avisar a entregar um total errado em silêncio.
- Tentar ligar N-N "na mão" como N-1. Isso não contorna a recusa: o modelo detecta a ambiguidade e recusa de qualquer forma, porque o problema é estrutural, não de sintaxe.
Nota
A detecção de fan-out e a resolução do caminho de join são GA-candidato — cobertas por um conjunto de testes de referência, com resultado idêntico a cada execução. O desempenho desse mesmo join em BigQuery de produção real continua Preview (NÃO MEDIDO sem credencial de nuvem).
Faça você mesmo#
No workspace de treino Aurora Varejo (abra /dashboards no console, editor de um painel, aba do modelo):
- Confirme que
filiaisestá ligada avendasporfilial_id, cardinalidade N-1. - Crie um visual novo e tente somar
filiais.meta(ou outra coluna numérica de uma dimensão) diretamente sobre esse join. - Observe a mensagem de recusa — anote exatamente o que ela diz.
- Em vez disso, crie a medida correta no fato:
SOMA(valor)sobrevendas, agrupada porfiliais.regiao. - Compare: a medida do fato funciona normalmente; a tentativa de somar a dimensão continua bloqueada.
- (Opcional) Tente ligar
produtosdiretamente a uma tabela hipotéticapromocoessem tabela-ponte e observe a recusa por ambiguidade.
Você terminou quando conseguir reproduzir o bloqueio de fan-out de propósito, explicar por que ele acontece e corrigi-lo movendo a soma para o fato certo.
Checagem rápida#
Três perguntas no final da aula, corrigidas no servidor. A aula só conta como concluída depois da checagem.
Documentação relacionada#
Capacidades ensinadas#
C05.1 · C05.4 — o selo exibido na aula é sempre o estado mais conservador entre as capacidades citadas; nada aqui é "GA".