Modelagem de dados e DAX em Power BI: boas práticas que separam relatório amador de corporativo
Modelagem DAX Power BI na prática: modelo estrela, tabela de datas, relacionamentos, CALCULATE, variáveis, time intelligence e performance no VertiPaq.
Modelagem DAX Power BI é o que decide se o relatório aguenta produção
A diferença entre um Power BI que funciona por anos e um que precisa ser refeito em seis meses raramente está no visual. Está na modelagem de dados e nas medidas DAX por trás dele. Vemos isso o tempo todo em diagnóstico: dashboard bonito na demo, número que muda conforme o relatório que você abre, relatório que trava com 200 mil linhas, medida copiada e colada sem que ninguém entenda o que ela faz. Modelagem DAX Power BI feita corretamente evita os três de uma vez — têm a mesma raiz: um modelo mal desenhado.
Este artigo vai direto às práticas que separam um relatório amador de um modelo semântico corporativo: arquitetura de tabelas, relacionamentos, medida versus coluna calculada, contexto do DAX, CALCULATE, time intelligence e performance no VertiPaq. Para arquitetura geral do ambiente de BI, o guia completo de Power BI para empresas no Brasil em 2026 cobre esse nível acima; aqui o foco é o modelo semântico.
Modelo estrela vence floco de neve e tabelão, e não é opinião
A primeira decisão de qualquer modelo é a arquitetura de tabelas. Existem três padrões possíveis, e só um deles escala bem no motor do Power BI.
Tabelão (single table) joga tudo — fato e dimensões — em uma tabela plana só, geralmente porque veio de uma planilha ou export de sistema. Funciona para um protótipo de 5 minutos e quebra em tudo mais: cardinalidade altíssima em toda coluna, sem reuso de contexto entre relatórios, DAX recalculando linha a linha porque não há relacionamento para o motor otimizar.
Floco de neve (snowflake) normaliza demais: dimensão de produto relacionada a categoria, relacionada a departamento, em cadeia. É boa prática em banco relacional transacional, mas em Power BI cada relacionamento adicional é um salto que o motor precisa percorrer para resolver um filtro, e cadeias longas tendem a gerar filtro inconsistente e DAX mais difícil de auditar.
Modelo estrela (star schema) é o padrão que recomendamos sempre: uma ou mais tabelas fato (transações, eventos, medições) no centro, relacionadas diretamente a tabelas de dimensão (produto, cliente, data, região) ao redor, sem dimensão relacionando com outra dimensão. É o desenho que o VertiPaq foi construído para otimizar, o que o DAX espera implicitamente em time intelligence, e o mais simples de auditar depois.
| Padrão | Quando aparece | Problema que causa em escala |
|---|---|---|
| Tabelão | Import direto de planilha/export sem tratamento | Cardinalidade alta, sem contexto de filtro reutilizável, DAX pesado |
| Floco de neve | Modelagem herdada de banco relacional normalizado | Relacionamentos em cadeia, filtro inconsistente, mais colunas técnicas expostas |
| Modelo estrela | Modelagem intencional para Power BI | Nenhum problema estrutural — é o padrão de referência |
Migrar de tabelão ou floco de neve para estrela não é cosmético: normalmente exige repensar a camada de ingestão e transformação antes do modelo, trabalho de engenharia de dados propriamente dita, não só de Power Query dentro do relatório.
Tabela de datas dedicada não é opcional em nenhum modelo com time intelligence
Toda tabela fato tem uma ou mais colunas de data. O erro comum é usar essas colunas diretamente nas visualizações e nas medidas de tempo. O correto é criar uma tabela de datas dedicada — via CALENDAR ou CALENDARAUTO em DAX, ou gerada no Power Query — marcada explicitamente como tabela de datas no modelo, com granularidade diária contínua, sem buracos, cobrindo todo o histórico mais o horizonte de planejamento futuro.
Praticamente todas as funções de time intelligence (TOTALYTD, SAMEPERIODLASTYEAR, DATEADD, PARALLELPERIOD) dependem dessa coluna contínua e marcada como tal. Sem isso, cálculos de "ano até a data" ou "mesmo período do ano anterior" podem retornar resultado errado silenciosamente — sem erro, sem aviso, só um número que não bate. É também a tabela de datas que permite relacionar múltiplas tabelas fato (vendas, orçamento, estoque) por uma dimensão de tempo comum, em vez de cada fato ter sua própria linha do tempo isolada.
Relacionamentos e cardinalidade definem como o filtro se propaga pelo modelo
Cada relacionamento no modelo tem duas propriedades que determinam o comportamento de qualquer medida: cardinalidade e direção do filtro.
Cardinalidade descreve quantas linhas de um lado se relacionam com quantas do outro. O padrão saudável em modelo estrela é um-para-muitos (1:N): um produto na dimensão, muitas linhas de venda na fato; uma data no calendário, muitas transações naquele dia. Relacionamentos muitos-para-muitos (N:N) existem e às vezes são necessários (um produto em múltiplas categorias simultâneas, por exemplo), mas exigem cuidado porque o motor não garante integridade referencial dos dois lados e o filtro fica mais difícil de prever. Use N:N só quando o negócio exige, nunca como atalho para não modelar direito.
Direção do filtro define se o filtro aplicado em uma tabela se propaga só para o lado "muitos" (direção única, o padrão recomendado) ou também para o lado "um" (bidirecional). Bidirecional parece conveniente porque "resolve" um filtro cruzado pontual, mas tem custo real: multiplica o caminho de propagação de contexto em modelos com várias tabelas fato, pode gerar ambiguidade entre caminhos, e degrada performance porque o motor avalia mais combinações a cada visual. Regra prática: direção única por padrão; bidirecional só com justificativa de negócio clara.
Medida ou coluna calculada: a pergunta que mais gera modelo lento
Essa é a decisão técnica mais mal compreendida por quem está começando em DAX, e o impacto em performance é direto.
Coluna calculada é computada linha a linha no processamento (refresh) do modelo, e o resultado fica armazenado fisicamente — ocupa espaço e é comprimido pelo VertiPaq como qualquer outra coluna. Faz sentido quando o resultado precisa ser usado como filtro, eixo de segmentação, agrupamento em tabela ou relacionamento, porque essas operações exigem que o valor já exista antes da consulta rodar.
Medida é calculada dinamicamente, no momento em que o visual é renderizado, dentro do contexto de filtro daquela célula específica. Não ocupa armazenamento e sempre reflete os filtros ativos. É o mecanismo certo para praticamente todo cálculo de negócio: soma condicionada, percentual, comparação de período, ranking.
| Critério | Coluna calculada | Medida |
|---|---|---|
| Quando é calculada | No refresh do modelo (processamento) | No momento da consulta (renderização do visual) |
| Ocupa armazenamento | Sim, fica materializada e comprimida | Não, é calculada sob demanda |
| Reage a filtro de contexto | Não — valor fixo por linha | Sim — recalcula conforme filtro ativo |
| Uso típico | Filtro, eixo, relacionamento, agrupamento de texto/categoria | KPI, soma condicional, % , comparação de período, ranking |
| Erro comum | Usar para somas e totais que deveriam ser dinâmicos | Tentar usar como eixo de filtro ou relacionamento |
| Custo em cardinalidade alta | Alto se a coluna tiver muitos valores distintos | Baixo — não adiciona coluna ao modelo |
Regra prática: se o resultado precisa aparecer como categoria, filtro ou eixo, é coluna calculada. Se é um número que muda conforme o que o usuário está olhando, é medida. Errar essa escolha na direção "tudo vira coluna calculada" é uma das causas mais comuns de modelo inchado e refresh lento que vemos em auditoria.
Contexto de linha e contexto de filtro são o alicerce de todo o DAX
DAX tem dois tipos de contexto de avaliação, e confundir os dois é a origem de quase todo erro conceitual em fórmulas mais complexas.
Contexto de linha existe quando o motor avalia uma expressão linha a linha — dentro de uma coluna calculada, ou de iteradoras como SUMX, FILTER, AVERAGEX. Nesse contexto, cada linha "sabe" seus próprios valores de coluna.
Contexto de filtro é o conjunto de filtros ativos no momento da avaliação — vindos de segmentações, filtros de página, de visual, ou impostos dentro de uma fórmula. Uma medida sempre é avaliada dentro de um contexto de filtro, mesmo sem filtro visível aplicado.
O ponto que costuma confundir: contexto de linha, por si só, não filtra a tabela inteira — só dá acesso aos valores daquela linha específica. Para transformar contexto de linha em contexto de filtro é preciso transição de contexto, que acontece automaticamente sempre que uma medida é chamada dentro de um contexto de linha (dentro de SUMX, por exemplo), ou explicitamente através de CALCULATE. Entender essa transição separa quem escreve DAX que "parece funcionar até certo ponto" de quem escreve DAX previsível.
CALCULATE é a função central do DAX porque ela reescreve o contexto de filtro
Se existe uma função que justifica estudar DAX a sério, é CALCULATE. Ela é a única (com sua variante CALCULATETABLE) capaz de modificar o contexto de filtro em que uma expressão é avaliada — adicionando filtros, removendo com ALL, ou substituindo com KEEPFILTERS.
Exemplo conceitual: uma medida de "Vendas Ano Anterior" não é outra fórmula de soma — é a mesma soma de vendas, avaliada dentro de um contexto de filtro deslocado um ano para trás.
Vendas Ano Anterior =
CALCULATE(
[Vendas Totais],
SAMEPERIODLASTYEAR('Calendário'[Data])
)
Aqui [Vendas Totais] não muda — o que muda é o contexto de filtro em que ela é avaliada, controlado pelo CALCULATE. Essa é a lógica por trás de praticamente toda medida de comparação, meta, percentual sobre o total e ranking em um modelo maduro. Quem entende CALCULATE entende DAX; quem não entende tende a empilhar IF e duplicar lógica em vez de reescrever contexto.
Variáveis (VAR) tornam o DAX legível, testável e mais rápido
Escrever fórmulas longas sem variáveis traz três problemas: difícil de ler, subexpressão recalculada mais de uma vez (custo desnecessário), e depuração que exige reconstruir mentalmente toda a árvore de avaliação.
VAR resolve os três. Declarada dentro da medida, a variável é avaliada uma única vez e reutilizada quantas vezes for referenciada no bloco RETURN.
Margem % =
VAR ReceitaTotal = [Receita]
VAR CustoTotal = [Custo]
VAR Margem = ReceitaTotal - CustoTotal
RETURN
DIVIDE(Margem, ReceitaTotal)
Além de mais legível, esse padrão evita recalcular [Receita] e [Custo] várias vezes na mesma medida — importante em modelos grandes, onde cada medida referenciada pode disparar uma varredura própria no motor. Usar DIVIDE() em vez de / também evita erro de divisão por zero sem IF adicional, porque a função já trata esse caso e retorna um valor alternativo (por padrão, em branco).
Time intelligence exige tabela de datas correta e vocabulário preciso
Com a tabela de datas marcada corretamente, as funções de time intelligence ficam relativamente diretas — mas cada uma responde a uma pergunta de negócio diferente, e usar a errada é um erro comum:
TOTALYTD/TOTALQTD/TOTALMTD: acumulado desde o início do ano/trimestre/mês até a data de contexto.SAMEPERIODLASTYEAR: mesmo intervalo de datas do contexto atual, deslocado um ano para trás — usado dentro deCALCULATE, não sozinho.DATEADD: desloca o contexto de datas por um número arbitrário de períodos, mais flexível queSAMEPERIODLASTYEAR.PARALLELPERIOD: parecido comDATEADD, mas retorna sempre o período completo (mês ou ano inteiro), não só o intervalo exato de dias do contexto.
O erro mais comum aqui não é sintático, é conceitual: comparar números de granularidade diferente (um YTD parcial de julho contra um ano fechado anterior) sem deixar isso explícito no nome da medida e no rótulo do visual — o que gera número "certo" mas mal interpretado por quem lê o relatório.
Performance no motor VertiPaq depende de cardinalidade, não de volume de linhas
Um dos maiores mitos sobre performance em Power BI é achar que o problema é "muitas linhas". O VertiPaq — que armazena o modelo em memória, colunarmente, comprimido — lida bem com dezenas de milhões de linhas quando o modelo está bem desenhado. O que realmente degrada performance é cardinalidade alta: número de valores distintos em uma coluna.
VertiPaq comprime cada coluna com base na repetição de valores — quanto menos valores distintos, melhor a compressão e mais rápida a varredura. Uma coluna de status com 5 valores distintos comprime quase para nada. Uma coluna de ID de transação com um valor distinto por linha praticamente não comprime, e ainda inflaciona qualquer coluna calculada ou relacionamento dependente dela.
Práticas que reduzem cardinalidade e melhoram performance real:
- Não traga colunas de granularidade desnecessária — timestamp com milissegundos quando a análise é diária, texto livre, IDs técnicos que ninguém usa em relatório.
- Divida datetime em data e hora separadas quando a hora for realmente necessária — datetime combinado multiplica a cardinalidade pela combinação de todos os valores possíveis.
- Prefira chaves numéricas a chaves de texto em relacionamentos — inteiros comprimem e comparam mais rápido que strings.
- Desative auto date/time do Power BI (ligado por padrão), que cria uma tabela de datas oculta por coluna de data, multiplicando objetos ocultos e cardinalidade sem controle.
- Evite medidas que forçam varredura de tabela inteira sem necessidade, como
CALCULATEcomALLsem motivo real para ignorar todos os filtros. - Prefira import a DirectQuery quando o volume permitir — o modelo em memória comprimido é ordens de grandeza mais rápido que reenviar consulta à fonte a cada interação.
Erros comuns de modelagem e a correção prática
| Erro comum | Por que acontece | Correção |
|---|---|---|
| Tudo em uma tabela só (tabelão) | Import direto de planilha sem tratamento prévio | Separar em fato e dimensões, modelo estrela |
| Sem tabela de datas dedicada | Uso direto da coluna de data da fato | Criar tabela de calendário e marcar como tabela de datas |
| Relacionamento bidirecional em tudo | Tentativa de "resolver" filtro cruzado sem entender a causa | Direção única por padrão; bidirecional só com justificativa pontual |
| Soma virar coluna calculada | Confusão entre linha a linha e agregação dinâmica | Usar medida para qualquer cálculo que deva reagir a filtro |
| Fórmula longa sem VAR | Hábito de escrever tudo em uma expressão só | Quebrar em variáveis nomeadas, uma por etapa lógica |
| Auto date/time ligado | Configuração padrão do Power BI Desktop não desativada | Desligar nas opções do arquivo antes de começar a modelar |
| Colunas técnicas visíveis para o usuário | Nenhuma organização de exibição aplicada | Ocultar colunas técnicas, usar pastas de exibição |
| Medida sem nome de negócio claro | Nome herdado da coluna de origem | Renomear com vocabulário do negócio, ex.: Receita Líquida YTD |
Organização do modelo é o que permite que outra pessoa mantenha depois de você
Modelagem tecnicamente correta ainda pode ser inutilizável se estiver desorganizada. Três práticas resolvem a maior parte disso:
Pastas de exibição (display folders) agrupam medidas e colunas relacionadas — "Vendas", "Time Intelligence", "Metas" — para que quem abre o modelo não veja uma lista plana de 80 itens sem ordem.
Ocultar colunas técnicas (chaves de relacionamento, colunas usadas internamente em outras medidas, colunas de auditoria) evita que o usuário final arraste a coluna errada para um visual e gere número sem sentido.
Nomear medidas com vocabulário de negócio, não com nome técnico de origem — Receita Líquida, não SUM_VLR_LIQ_TB01. Parece cosmético, mas permite que uma pessoa de negócio explore o modelo em self-service sem depender de quem construiu.
Modelo bem organizado também é pré-requisito de governança: sem nomenclatura e pastas consistentes, aplicar controle de acesso, catalogação e certificação de modelo em escala fica praticamente inviável — não há como auditar o que não está nomeado com clareza.
Perguntas frequentes
Modelo estrela é sempre melhor que floco de neve? Para Power BI, sim, na prática recomendamos sempre. VertiPaq e as funções DAX de time intelligence são otimizados para relacionamento direto entre fato e dimensão. Floco de neve pode até funcionar, mas adiciona complexidade sem ganho real.
Quando vale a pena usar relacionamento muitos-para-muitos? Só quando o negócio realmente tem essa relação — uma conta bancária compartilhada por múltiplos titulares, por exemplo. Não use N:N como atalho para não resolver a granularidade corretamente.
Coluna calculada e medida podem ter o mesmo nome de fórmula? Tecnicamente sim em contextos diferentes, mas evite: gera confusão sobre qual está sendo referenciada e dificulta manutenção.
Por que minha medida de ano anterior retorna resultado errado mesmo usando SAMEPERIODLASTYEAR? Na maioria dos casos é porque a tabela de datas não está marcada como tal, tem buracos na sequência diária, ou não cobre o intervalo necessário. Verifique isso antes de suspeitar da fórmula.
Quantas medidas um modelo corporativo costuma ter? Varia com a complexidade do negócio, mas modelos maduros costumam ter dezenas a poucas centenas de medidas organizadas em pastas — o que importa é a organização, não o número.
Vale a pena reescrever um modelo antigo em vez de só otimizar as fórmulas? Depende de onde está o problema. Se o modelo já é estrela com tabela de datas correta, otimizar DAX pode resolver. Se a base é tabelão ou floco de neve com relacionamentos bidirecionais espalhados, geralmente compensa reestruturar — um diagnóstico rápido identifica qual dos dois cenários você tem.
Modelagem correta é investimento, não custo extra
Boa modelagem DAX Power BI não aparece no relatório final como recurso visível — aparece como o relatório que carrega rápido, os números que batem entre páginas e o modelo que sobrevive a dois anos de crescimento sem precisar ser refeito do zero. É trabalho invisível, mas sustenta tudo o que é visível. Se seu ambiente atual mostra sinais dos erros descritos aqui — relatório lento, números divergentes, fórmulas que ninguém mais entende — vale um diagnóstico antes de empilhar mais relatório em cima de uma base frágil. Veja como estruturamos isso em projetos reais nos nossos cases, entenda o investimento envolvido em quanto custa implementar Power BI em uma empresa em 2026, ou conheça nossos serviços de Power BI. Para discutir o estado atual do seu modelo, fale com a gente.
Quer aplicar isso na sua empresa?
A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.
Falar com um especialista