Slowly Changing Dimensions (SCD) é um padrão de modelagem dimensional que define como tratar mudanças em atributos de dimensões ao longo do tempo. A escolha do tipo depende de se o histórico precisa ser preservado e como o negócio quer enxergar os dados.

Dimensões com SCD são comuns em tabelas como dim_cliente, dim_produto, dim_funcionario, onde atributos como endereço, preço ou cargo mudam eventualmente.

Tipos de SCD

Tipo 0: Imutável

O valor original nunca é alterado. Qualquer mudança na fonte é ignorada.

Quando usar: atributos que, por definição, não devem mudar (ex: data de nascimento, CPF, código de origem).

Tipo 1: Sobrescrever (sem histórico)

A mudança sobrescreve o valor anterior. Não há histórico.

-- Atualiza direto, sem preservar o valor antigo
UPDATE dim_cliente
SET cidade = 'São Paulo'
WHERE cliente_id = 42;

Quando usar: correções de erro (o valor antigo estava errado) ou quando o histórico não tem valor analítico.

Limitação: consultas históricas refletem o valor atual, não o valor da época.

Tipo 2: Nova linha por versão (histórico completo)

Cada mudança cria uma nova linha com um período de validade. É o tipo mais comum e poderoso.

cliente_id | nome  | cidade        | inicio_vigencia | fim_vigencia | is_current
42         | Ana   | Belo Horizonte| 2022-01-01      | 2024-06-30   | false
42         | Ana   | São Paulo     | 2024-07-01      | 9999-12-31   | true
-- Fechar versão anterior
UPDATE dim_cliente
SET fim_vigencia = '2024-06-30', is_current = false
WHERE cliente_id = 42 AND is_current = true;
 
-- Inserir nova versão
INSERT INTO dim_cliente (cliente_id, nome, cidade, inicio_vigencia, fim_vigencia, is_current)
VALUES (42, 'Ana', 'São Paulo', '2024-07-01', '9999-12-31', true);

Colunas típicas de controle:

  • surrogate_key: PK única da dimensão (gerada, não da fonte)
  • inicio_vigencia / fim_vigencia: intervalo de validade
  • is_current: flag booleano para linha ativa
  • versao: contador de versões (opcional)

Quando usar: quando precisar responder “qual era o endereço do cliente quando ele fez o pedido?“. Exige join pela surrogate key + data da transação.

Tipo 3: Coluna adicional (histórico limitado)

Adiciona uma coluna para o valor anterior. Preserva apenas a última mudança.

cliente_id | cidade_atual | cidade_anterior | data_mudanca
42         | São Paulo    | Belo Horizonte  | 2024-07-01

Quando usar: quando só importa saber o valor imediatamente anterior. Simples, mas limitado: apenas uma mudança rastreada por registro.

Tipo 4: Tabela histórica separada

A dimensão principal tem apenas o valor atual. Uma tabela separada armazena o histórico completo.

-- dim_cliente (só atual)
cliente_id | nome | cidade

-- dim_cliente_historico (todas as versões)
cliente_id | nome | cidade | vigencia_inicio | vigencia_fim

Quando usar: quando a dimensão é muito larga e o histórico raramente é consultado. Mantém a dimensão principal pequena e performática.

Implementação com Delta Lake (SCD Tipo 2)

from delta.tables import DeltaTable
from pyspark.sql import functions as F
 
novos_dados = spark.table("staging.clientes")
dim = DeltaTable.forName(spark, "gold.dim_cliente")
 
# 1. Fechar registros que mudaram
dim.alias("alvo").merge(
    novos_dados.alias("origem"),
    "alvo.cliente_id = origem.cliente_id AND alvo.is_current = true"
).whenMatchedUpdate(
    condition="alvo.cidade <> origem.cidade",
    set={
        "fim_vigencia": F.current_date(),
        "is_current": F.lit(False)
    }
).execute()
 
# 2. Inserir novas versões
novos_dados.withColumn("inicio_vigencia", F.current_date()) \
           .withColumn("fim_vigencia", F.lit("9999-12-31").cast("date")) \
           .withColumn("is_current", F.lit(True)) \
           .write.format("delta").mode("append").saveAsTable("gold.dim_cliente")

No Databricks com Lakeflow Declarative Pipelines, o APPLY CHANGES INTO automatiza SCD Tipo 1 e Tipo 2.

-- Lakeflow: SCD Tipo 2 automático
APPLY CHANGES INTO LIVE.dim_cliente
FROM STREAM(LIVE.staging_clientes)
KEYS (cliente_id)
APPLY AS DELETE WHEN operacao = 'DELETE'
SEQUENCE BY updated_at
STORED AS SCD TYPE 2;

Quando usar cada tipo

TipoHistóricoComplexidadeCaso de uso típico
0NenhumMínimaAtributos imutáveis
1NenhumBaixaCorreções de erro
2CompletoAltaAnálise histórica precisa
31 versãoMédiaComparação antes/depois
4Completo (tabela separada)MédiaDimensões grandes com histórico raro

Relação com CDC

CDC é o mecanismo que captura as mudanças na fonte. SCD é o padrão que define como essas mudanças são aplicadas na dimensão. O CDC alimenta o SCD.

Ver também: pipeline-de-dados | arquitetura-medalhao | databricks-delta-lake | databricks-lakeflow-pipelines | cdc-change-data-capture | engenharia-de-dados