Slowly Changing Dimensions Tipo 2: preservar histórico no data warehouse
João Barros
20 de March de 2025
2 min de leitura
As Slowly Changing Dimensions (SCD) resolvem um problema fundamental em data warehousing: o que fazer quando um atributo de uma dimensão muda? A resposta depende da necessidade de negócio de preservar o estado histórico.
Os 3 tipos principais
TIPO 1 — Sobrescrever (sem histórico):
Antes: Cliente X — Segmento: PME
Depois da mudança: Cliente X — Segmento: Enterprise
→ O passado parece sempre Enterprise. Bom para correcções de erros.
TIPO 2 — Novo registo (com histórico completo):
Registo 1: Cliente X, Segmento PME, valid_from: 2020-01-01, valid_to: 2023-12-31, is_current: 0
Registo 2: Cliente X, Segmento Enterprise, valid_from: 2024-01-01, valid_to: 9999-12-31, is_current: 1
→ Análises históricas mostram PME nas vendas até 2023. O mais usado.
TIPO 3 — Coluna adicional (apenas último + anterior):
Cliente X — Segmento_Actual: Enterprise, Segmento_Anterior: PME
→ Só preserva 1 mudança. Raro mas útil para reorganizações.
Implementar SCD Tipo 2 com MERGE
-- Processo ETL: aplicar alterações da fonte à dimensão
MERGE dbo.DimCliente AS tgt
USING (SELECT nk_cliente, nome, segmento, pais FROM stg.Clientes) AS src
ON tgt.nk_cliente = src.nk_cliente AND tgt.is_current = 1
-- Tipo 1: actualizar atributos que não guardam histórico (nome - correcção de erro)
WHEN MATCHED AND tgt.nome <> src.nome
THEN UPDATE SET tgt.nome = src.nome
-- Tipo 2: fechar registo actual e inserir novo
WHEN MATCHED AND tgt.segmento <> src.segmento
THEN UPDATE SET tgt.valid_to = CAST(GETDATE() AS DATE), tgt.is_current = 0;
-- Inserir novos registos: clientes novos + versão nova dos SCD2
INSERT INTO dbo.DimCliente (nk_cliente, nome, segmento, pais, valid_from, valid_to, is_current)
SELECT src.nk_cliente, src.nome, src.segmento, src.pais,
CAST(GETDATE() AS DATE), '9999-12-31', 1
FROM stg.Clientes src
LEFT JOIN dbo.DimCliente tgt ON src.nk_cliente = tgt.nk_cliente AND tgt.is_current = 1
WHERE tgt.sk_cliente IS NULL
OR (tgt.sk_cliente IS NOT NULL AND tgt.segmento <> src.segmento);
Join correcto em relatórios
-- Para análise histórica correcta, usar a surrogate key da data da transacção
SELECT
v.receita,
c.segmento, -- segmento do cliente NO MOMENTO da venda
d.ano
FROM dbo.FactVendas v
JOIN dbo.DimCliente c ON v.sk_cliente = c.sk_cliente -- SK preserva contexto histórico
JOIN dbo.DimData d ON v.sk_data = d.sk_data
Conclusão
SCD Tipo 2 é a espinha dorsal da análise histórica correcta. Sem ela, relatórios históricos mostram clientes com o segmento actual, não o que tinham quando compraram. A surrogate key é o mecanismo que preserva o contexto — nunca faça joins pela chave natural em factos históricos.