Como criar uma Dimension Degenerate (Degenerate Dimension) em Modelação de Dados (Kimball)
Este tutorial mostra como criar uma Dimension Degenerate (degenerada) seguindo os princípios Kimball: quando e porque manter atributos de transacção directamente na fact table em vez de criar uma dimensão separada. Aprender a modelar degenerate dimensions ajuda a simplificar consultas e a reduzir joins desnecessários em cenários de faturas, pedidos ou transacções únicas.
Pré-requisitos
- Conhecimentos básicos de SQL (SELECT, JOIN, INSERT).
- Compreensão do conceito de star schema e de fact/dimension.
- Uma base de dados de teste (por exemplo SQL Server, PostgreSQL ou MySQL).
Passo 1: Identificar quando usar uma Degenerate Dimension
Uma Degenerate Dimension é um atributo ligado à transacção que não necessita de identidade ou atributos adicionais que justifiquem uma dimensão separada. Exemplos típicos: número de fatura, código de transacção, referência externa. Use-a quando o atributo é único por linha de fact e não vai ser partilhado entre fact tables.
Passo 2: Verificar requisitos de consulta e granularidade
Antes de decidir manter o campo na fact table, confirme que os relatórios não precisam de atributos adicionais, histórico ou conformidade que exigiriam uma dimensão. Pense em performance: se muitos relatórios só filtram por esse campo, uma Degenerate Dimension (na fact) reduz joins.
Passo 3: Definir a estrutura da fact table com a Degenerate Dimension
Crie a fact table incluindo a chave da fact (surrogate key ou natural), medidas e o campo degenerado como coluna não referenciada a uma dimensão. Garanta o tipo de dados adequado e indexação quando necessário para filtros frequentes.
-- Exemplo em SQL (SQL Server sintaxe genérica) CREATE TABLE FactSales (
SaleID BIGINT PRIMARY KEY, -- surrogate key da fact
InvoiceNumber VARCHAR(50) NOT NULL, -- Degenerate Dimension
CustomerKey INT NOT NULL, -- FK para Dimension Customer
ProductKey INT NOT NULL, -- FK para Dimension Product
SaleDateKey INT NOT NULL, -- FK para Dimension Date
Quantity INT,
Amount DECIMAL(18,2)
);
-- Índice para procurar por InvoiceNumber rapidamente
CREATE INDEX IX_FactSales_InvoiceNumber ON FactSales(InvoiceNumber);
Passo 4: Carga ETL/ELT: povoar a Degenerate Dimension
No processo ETL/ELT, apenas mapeie o valor do campo de transacção directamente para a coluna da fact. Não tente criar uma surrogate key separada. Trate duplicados e normalização apenas se necessário para garantir integridade (ex.: limpeza de espaços, formato consistente).
-- Exemplo simples de INSERT durante ETL INSERT INTO FactSales (SaleID, InvoiceNumber, CustomerKey, ProductKey, SaleDateKey, Quantity, Amount)
SELECT
s.SourceSaleID, -- pode ser surrogate gerado
TRIM(s.InvoiceNo),
d.CustomerKey,
p.ProductKey,
dd.DateKey,
s.Quantity,
s.TotalAmount
FROM StagingSales s
JOIN DimCustomer d ON s.CustomerID = d.CustomerID
JOIN DimProduct p ON s.ProductCode = p.ProductCode
JOIN DimDate dd ON CAST(s.SaleDate AS DATE) = dd.FullDate
WHERE s.IsActive = 1;
Passo 5: Tratar erros comuns
Erros comuns: 1) Tratar InvoiceNumber como dimensão e depois descobrir que é única por linha — cria redundância. 2) Não indexar InvoiceNumber quando usado em filtros — consultas lentas. 3) Assumir imutabilidade quando os números podem mudar (ex.: correcção de fatura) — definir política: actualizar a fact ou criar evento de correcção.
Verificar o resultado
Confirme que a Degenerate Dimension funciona executando consultas reais: filtragem por InvoiceNumber, agregações por Customer e verificação dos planos de execução. Testes a realizar:
- SELECT por InvoiceNumber — deve devolver a linha correcta e ser rápido.
- Contagens de invoices distintos — comparar com a origem.
- Relatórios que agregam por Customer/Date — garantir que não há excesso de joins.
-- Exemplos de verificação
-- 1) Procurar fatura específica
SELECT * FROM FactSales WHERE InvoiceNumber = 'INV-2026-0001';
-- 2) Contar invoices distintos por dia
SELECT SaleDateKey, COUNT(DISTINCT InvoiceNumber) AS NumInvoices
FROM FactSales
GROUP BY SaleDateKey;
Conclusão
Manter uma Degenerate Dimension na fact table simplifica o modelo quando o atributo é único por transacção e não tem atributos próprios. Próximos passos: avaliar indexação, políticas de actualização e impacto em relatórios. Dica: documente sempre por que um campo é degenerado — isso poupará tempo à equipa quando estiverem a optimizar consultas.