Como implementar SCD Tipo 1 num Data Warehouse
Numa dimensão SCD Tipo 1 de um Data Warehouse, quando um atributo muda o valor antigo é sobrescrito pelo novo e não se guarda histórico. É a técnica ideal para corrigir erros de dados ou manter atributos de referência sempre atuais, como a cidade ou o segmento de um cliente — casos em que o valor anterior deixa de ter interesse. A seguir vais implementar SCD Tipo 1 passo a passo, com um único comando MERGE em SQL que atualiza o que mudou e insere o que é novo, sem duplicar linhas.
Pré-requisitos
- Um SQL Server 2008 ou superior, ou uma base de dados Azure SQL.
- Permissões para criar tabelas e inserir ou atualizar dados.
- Noções básicas de SQL e do conceito de tabela de dimensão.
Passo 1: Criar a tabela de dimensão
A dimensão tem uma surrogate key (uma chave técnica gerada automaticamente pela coluna IDENTITY) e a business key, que identifica cada cliente na origem. Os restantes atributos são os campos que queremos manter atualizados, e a coluna UpdatedAt regista quando a linha foi alterada pela última vez.
CREATE TABLE dbo.DimCustomer
(
CustomerSK INT IDENTITY(1,1) PRIMARY KEY, -- surrogate key
CustomerID INT NOT NULL, -- business key
Name NVARCHAR(100) NOT NULL,
City NVARCHAR(80) NULL,
Segment NVARCHAR(40) NULL,
UpdatedAt DATETIME2 NOT NULL
);
Passo 2: Carregar a origem para staging
Coloca o retrato mais recente dos clientes numa tabela de staging. É esta tabela que o MERGE vai comparar com a dimensão. Numa carga real seria preenchida a partir do sistema de origem; aqui inserimos duas linhas à mão para o exemplo, em que a Ana mudou de cidade e o Bruno ainda não existe na dimensão.
CREATE TABLE dbo.StgCustomer
(
CustomerID INT NOT NULL,
Name NVARCHAR(100) NOT NULL,
City NVARCHAR(80) NULL,
Segment NVARCHAR(40) NULL
);
INSERT INTO dbo.StgCustomer (CustomerID, Name, City, Segment) VALUES
(1, N'Ana Silva', N'Porto', N'Retail'), -- City changed to Porto
(2, N'Bruno Costa', N'Braga', N'Enterprise'); -- new customer
Passo 3: Aplicar SCD Tipo 1 com MERGE
O comando MERGE resolve tudo numa só instrução. O bloco WHEN MATCHED trata dos clientes que já existem: só sobrescreve os atributos quando há mesmo uma diferença, evitando escritas desnecessárias. O bloco WHEN NOT MATCHED BY TARGET insere os clientes novos.
MERGE dbo.DimCustomer AS target
USING dbo.StgCustomer AS source
ON target.CustomerID = source.CustomerID
WHEN MATCHED AND (
target.Name <> source.Name
OR target.City <> source.City
OR target.Segment <> source.Segment
) THEN
UPDATE SET
target.Name = source.Name,
target.City = source.City,
target.Segment = source.Segment,
target.UpdatedAt = SYSUTCDATETIME()
WHEN NOT MATCHED BY TARGET THEN
INSERT (CustomerID, Name, City, Segment, UpdatedAt)
VALUES (source.CustomerID, source.Name, source.City, source.Segment, SYSUTCDATETIME());
Termina sempre o comando MERGE com ponto e vírgula: no SQL Server é obrigatório e evita um erro de sintaxe difícil de encontrar.
Passo 4: Comparação segura com valores NULL
O operador <> devolve desconhecido quando um dos lados é NULL, por isso uma mudança de ou para NULL pode não ser detetada. Para uma comparação robusta, troca a condição do WHEN MATCHED por um EXCEPT, que considera dois valores NULL como iguais:
WHEN MATCHED AND EXISTS (
SELECT source.Name, source.City, source.Segment
EXCEPT
SELECT target.Name, target.City, target.Segment
) THEN
UPDATE SET
target.Name = source.Name,
target.City = source.City,
target.Segment = source.Segment,
target.UpdatedAt = SYSUTCDATETIME()
Verificar o resultado
Executa o MERGE e depois consulta a dimensão. A cidade da Ana deve aparecer como Porto (o valor antigo desapareceu) e o Bruno deve surgir como uma linha nova, sem duplicados.
SELECT CustomerSK, CustomerID, Name, City, Segment, UpdatedAt
FROM dbo.DimCustomer
ORDER BY CustomerID;
Corre o mesmo MERGE uma segunda vez sem alterar a origem: nenhuma linha é atualizada. Essa idempotência confirma que o SCD Tipo 1 está a funcionar como esperado.
Conclusão
Com um único MERGE, a dimensão passa a refletir sempre o estado mais recente da origem — o objetivo do SCD Tipo 1. O próximo passo é decidir, atributo a atributo, o que deve guardar histórico: para esses casos escolherias SCD Tipo 2, muitas vezes na mesma tabela. Olhando para a tua dimensão, que atributos fazem sentido sobrescrever e quais preferes preservar ao longo do tempo?