Como modelar um esquema em floco de neve num Data Warehouse
Um esquema em floco de neve (snowflake schema) organiza um Data Warehouse normalizando as dimensões em tabelas mais pequenas e ligadas entre si. O resultado é menos redundância e dimensões mais fáceis de manter — útil quando uma dimensão tem muitos atributos repetidos, como categorias de produto ou localizações geográficas.
Pré-requisitos
- Um Data Warehouse ou base de dados relacional (SQL Server, Azure SQL, PostgreSQL, etc.).
- Conhecer o conceito de esquema em estrela (star schema), com tabela de factos e dimensões.
- Noções básicas de SQL (
CREATE TABLE,JOIN, chaves primárias e estrangeiras).
Passo 1: Perceber a diferença entre estrela e floco de neve
No esquema em estrela, cada dimensão é uma única tabela "achatada" (desnormalizada) que repete valores. No esquema em floco de neve, essa dimensão é dividida em várias tabelas relacionadas, seguindo as regras da normalização. A tabela de factos continua no centro; a diferença está em como as dimensões se ramificam.
Imagina uma dimensão de produto que inclui categoria e subcategoria. No modelo em estrela, o nome da categoria repete-se em cada linha de produto. No floco de neve, a categoria passa para a sua própria tabela e o produto guarda apenas uma chave.
Regra prática: usa o floco de neve para dimensões grandes e muito repetitivas; mantém o esquema em estrela para dimensões pequenas onde a rapidez das consultas é prioritária.
Passo 2: Identificar a dimensão a normalizar
Escolhe uma dimensão com atributos claramente hierárquicos ou muito repetidos. Um bom candidato é Dim_Produto, que costuma conter produto, subcategoria e categoria — uma hierarquia natural de três níveis. Separar estes níveis evita atualizar dezenas ou centenas de linhas quando o nome de uma categoria muda, porque esse nome passa a existir num só sítio.
Passo 3: Criar as tabelas normalizadas
Vamos partir a dimensão de produto em três tabelas ligadas por chaves estrangeiras: categoria, subcategoria e produto. Cada tabela usa uma surrogate key (uma chave numérica própria do Data Warehouse) como chave primária, o que mantém as ligações estáveis mesmo que os identificadores de origem mudem.
CREATE TABLE Dim_Categoria (
categoria_key INT PRIMARY KEY,
nome_categoria VARCHAR(100)
);
CREATE TABLE Dim_Subcategoria (
subcategoria_key INT PRIMARY KEY,
nome_subcategoria VARCHAR(100),
categoria_key INT REFERENCES Dim_Categoria(categoria_key)
);
CREATE TABLE Dim_Produto (
produto_key INT PRIMARY KEY,
nome_produto VARCHAR(150),
subcategoria_key INT REFERENCES Dim_Subcategoria(subcategoria_key)
);
Repara na cadeia: Dim_Produto aponta para Dim_Subcategoria, que por sua vez aponta para Dim_Categoria. É esta ramificação que dá o formato de floco de neve.
Passo 4: Ligar a tabela de factos
A tabela de factos liga-se apenas ao nível mais detalhado da dimensão — neste caso, Dim_Produto. Os níveis superiores são alcançados através das tabelas intermédias, seguindo a cadeia de chaves.
CREATE TABLE Fact_Vendas (
venda_key BIGINT PRIMARY KEY,
produto_key INT REFERENCES Dim_Produto(produto_key),
data_key INT,
quantidade INT,
valor_total DECIMAL(12,2)
);
Passo 5: Consultar os dados com JOINs
Para obter as vendas por categoria, percorre a cadeia de tabelas com JOIN até chegar à categoria:
SELECT c.nome_categoria,
SUM(f.valor_total) AS total_vendas
FROM Fact_Vendas AS f
JOIN Dim_Produto AS p ON f.produto_key = p.produto_key
JOIN Dim_Subcategoria AS s ON p.subcategoria_key = s.subcategoria_key
JOIN Dim_Categoria AS c ON s.categoria_key = c.categoria_key
GROUP BY c.nome_categoria
ORDER BY total_vendas DESC;
Repara que o floco de neve exige mais JOIN do que o esquema em estrela. Em troca, cada nome de categoria existe uma única vez, o que poupa espaço e simplifica atualizações. Em bases de dados analíticas modernas o custo destes JOIN costuma ser baixo, mas convém testá-lo com o teu volume real de dados.
Verificar o resultado
Para confirmar que o modelo está correto, valida três coisas:
- Cada
subcategoria_keyemDim_Produtoexiste emDim_Subcategoria(integridade referencial). - A query do Passo 5 devolve uma linha por categoria, sem duplicados.
- Não há nomes de categoria repetidos em
Dim_Categoria.
Podes correr esta verificação rápida para detetar categorias duplicadas:
SELECT nome_categoria, COUNT(*) AS repeticoes
FROM Dim_Categoria
GROUP BY nome_categoria
HAVING COUNT(*) > 1;
Se a query não devolver nenhuma linha, não existem categorias repetidas e a normalização está bem feita.
Conclusão
Já sabes montar um esquema em floco de neve: normalizas uma dimensão em tabelas ligadas por chaves estrangeiras e ajustas as queries com JOIN adicionais. Usa esta abordagem quando a poupança de espaço e a facilidade de manutenção compensam os joins extra; caso contrário, o esquema em estrela pode ser mais rápido e simples. Qual das tuas dimensões tem mais valores repetidos e seria a primeira candidata a normalizar?