Dados · Pleno

Modelagem dimensional: fato, dimensão e o data warehouse

O modelo relacional normalizado é perfeito para um sistema que processa pedidos um a um. Mas quando o gestor pergunta "qual a receita por região, por mês, por categoria de produto, nos últimos três anos?", esse mesmo modelo trava. A modelagem dimensional nasceu para resolver justamente esse tipo de pergunta analítica.

OLTP vs OLAP: dois mundos diferentes

Sistemas transacionais (OLTP) são otimizados para muitas escritas pequenas e consistentes — inserir um pedido, atualizar um estoque. Por isso são normalizados. Já a análise (OLAP) faz poucas consultas, mas enormes, varrendo milhões de linhas e cruzando muitas dimensões.

O modelo normalizado, com suas dezenas de tabelas, exige JOINs caríssimos para essas perguntas. A modelagem dimensional reorganiza os dados deliberadamente para a leitura analítica — uma desnormalização proposital, como antecipamos em normalização.

Tabela fato: o que aconteceu

A tabela fato guarda os eventos mensuráveis do negócio — uma venda, um clique, um embarque. Suas colunas são de dois tipos: as métricas (valores numéricos que você soma e calcula, como quantidade e valor) e as chaves estrangeiras que apontam para as dimensões. A fato tende a ser longa e estreita: muitíssimas linhas, poucas colunas.

Tabela dimensão: o contexto

As dimensões dão contexto às métricas: quem, o quê, quando, onde. Dimensão de cliente, de produto, de tempo, de loja. São tabelas curtas e largas: relativamente poucas linhas, muitas colunas descritivas. É por elas que você filtra e agrupa ("vendas por categoria de produto" usa a dimensão produto).

Star schema: o desenho clássico

Quando você coloca a fato no centro e as dimensões ao redor, ligadas diretamente a ela, o desenho lembra uma estrela — daí star schema:

      dim_tempo      dim_produto
          \             /
           \           /
            +---------------+
            |  fato_vendas  |
            | (qtd, valor)  |
            +---------------+
           /           \
          /             \
     dim_cliente      dim_loja

Cada dimensão se conecta à fato por uma chave. Como as dimensões são desnormalizadas (sem subníveis), basta um JOIN por dimensão — rápido e simples de consultar.

Snowflake: quando a dimensão se ramifica

No snowflake schema, as dimensões são normalizadas em subtabelas: a dimensão produto se desdobra em categoria, que se desdobra em departamento. Economiza espaço e reduz redundância, mas adiciona JOINs e complica a consulta.

AspectoStar schemaSnowflake
DimensõesDesnormalizadas (planas)Normalizadas (ramificadas)
JOINs por consultaMenosMais
RedundânciaMaiorMenor
Performance de leituraMelhorPior

Na prática, o star schema costuma vencer no analítico, porque ali leitura rápida vale mais que economia de espaço.

Grão: a decisão mais importante

O grão (grain) define o que uma linha da fato representa. Uma linha por venda? Por item da venda? Por dia agregado? Essa é a primeira decisão de qualquer modelo dimensional, porque ela determina o nível de detalhe possível. Grão fino dá flexibilidade; grão grosso economiza espaço mas perde detalhe. Misturar grãos na mesma fato é um erro clássico.

OLTP otimiza para escrever um fato de cada vez; dimensional otimiza para ler milhões de fatos de uma vez. Não é que um seja melhor — eles resolvem problemas opostos, e você precisa do modelo certo para a pergunta certa.

É comum em entrevista pedir para você desenhar um star schema a partir de um cenário ("modele as vendas de um e-commerce") e justificar o grão escolhido. No dia a dia isso aparece quando você projeta um data warehouse ou tenta entender por que um dashboard demora a carregar.

Conclusão

A modelagem dimensional separa fatos (métricas mensuráveis) de dimensões (contexto), organiza tudo num star schema otimizado para leitura, e gira em torno da escolha do grão. Entender por que ela difere do modelo OLTP normalizado é o passo que abre a porta do mundo analítico e do data warehouse.

The normalized relational model is perfect for a system that processes orders one at a time. But when a manager asks "what's the revenue by region, by month, by product category, over the last three years?", that same model chokes. Dimensional modeling was born to solve exactly this kind of analytical question.

OLTP vs OLAP: two different worlds

Transactional systems (OLTP) are optimized for many small, consistent writes — inserting an order, updating stock. That's why they're normalized. Analysis (OLAP), on the other hand, runs few queries, but huge ones, scanning millions of rows and cutting across many dimensions.

The normalized model, with its dozens of tables, requires very expensive JOINs for these questions. Dimensional modeling deliberately reorganizes the data for analytical reads — a purposeful denormalization, as we anticipated in normalization.

Fact table: what happened

The fact table stores the measurable events of the business — a sale, a click, a shipment. Its columns are of two kinds: measures (numeric values you sum and compute on, like quantity and amount) and the foreign keys that point to the dimensions. The fact table tends to be long and narrow: a huge number of rows, few columns.

Dimension table: the context

Dimensions give context to the measures: who, what, when, where. Customer dimension, product, time, store. They're short and wide tables: relatively few rows, many descriptive columns. They're what you filter and group by ("sales by product category" uses the product dimension).

Star schema: the classic design

When you put the fact table in the center and the dimensions around it, linked directly to it, the drawing looks like a star — hence star schema:

      dim_time       dim_product
          \             /
           \           /
            +---------------+
            |  fact_sales   |
            | (qty, amount) |
            +---------------+
           /           \
          /             \
     dim_customer      dim_store

Each dimension connects to the fact table through a key. Since dimensions are denormalized (no sub-levels), you need just one JOIN per dimension — fast and simple to query.

Snowflake: when the dimension branches out

In a snowflake schema, dimensions are normalized into sub-tables: the product dimension splits into category, which splits into department. It saves space and reduces redundancy, but adds JOINs and complicates the query.

AspectStar schemaSnowflake
DimensionsDenormalized (flat)Normalized (branched)
JOINs per queryFewerMore
RedundancyHigherLower
Read performanceBetterWorse

In practice, the star schema usually wins in analytics, because there fast reads matter more than saving space.

Grain: the most important decision

The grain defines what one row of the fact table represents. One row per sale? Per sale item? Per aggregated day? This is the first decision of any dimensional model, because it determines the level of detail possible. Fine grain gives flexibility; coarse grain saves space but loses detail. Mixing grains in the same fact table is a classic mistake.

OLTP optimizes for writing one fact at a time; dimensional optimizes for reading millions of facts at once. It's not that one is better — they solve opposite problems, and you need the right model for the right question.

In interviews it's common to be asked to draw a star schema from a scenario ("model the sales of an e-commerce store") and justify the grain you chose. Day to day, this shows up when you design a data warehouse or try to understand why a dashboard is slow to load.

Conclusion

Dimensional modeling separates facts (measurable metrics) from dimensions (context), organizes everything in a star schema optimized for reading, and revolves around the choice of grain. Understanding why it differs from the normalized OLTP model is the step that opens the door to the analytical world and the data warehouse.

Leia também

Voltar à trilhaBack to the track