A Arquitetura Medalhão (Medallion Architecture) é um padrão de design para organizar dados em um data-lake-lakehouse em camadas progressivas de qualidade, cada uma com um propósito distinto.

Popularizada pela Databricks com o Delta Lake, é agnóstica de tecnologia e pode ser implementada com qualquer stack moderna. No Databricks, o padrão é implementado com Delta Lake e Lakeflow Declarative Pipelines.

As três camadas

flowchart LR
    F([Fonte]) --> B[(Bronze - raw)]
    B --> S[(Silver - limpo)]
    S --> G[(Gold - agregado)]
    G --> C([BI / ML])

Bronze: dados brutos

  • Cópia fiel dos dados da fonte, sem transformações
  • Preserva o histórico completo (append-only ou com versionamento)
  • Schema-on-read: não impõe estrutura rígida
  • Serve como ponto de re-processamento caso algo dê errado downstream
  • Formato típico: Parquet, Delta, JSON, Avro. O formato segue o que vier da fonte

Regra de ouro: nunca delete dados da Bronze. Em caso de erro, reprocesse a partir daqui.

Silver: dados limpos e conformados

  • Dados limpos, deduplicados e com schema definido
  • Joins entre domínios (ex: pedidos + clientes), tipagem correta, tratamento de nulos
  • Granularidade próxima à da fonte, mas confiável
  • Usado por analistas que precisam de dados brutos confiáveis e por pipelines de ML

Gold: dados agregados e orientados ao negócio

  • Modelos analíticos prontos para consumo: métricas, KPIs, tabelas dimensionais
  • Agnóstico de fonte. O consumidor não precisa saber de onde veio cada campo
  • Otimizado para leitura: particionamento, Z-ordering, materialização de agregações custosas
  • Alimenta dashboards, relatórios e APIs de produto

Exemplo de estrutura no storage

s3://meu-datalake/
├── bronze/
│   ├── crm/clientes/
│   ├── erp/pedidos/
│   └── kafka/eventos/
├── silver/
│   ├── clientes/
│   ├── pedidos/
│   └── sessoes/
└── gold/
    ├── kpis_diarios/
    ├── churn_features/
    └── receita_por_produto/

Implementação com Delta Lake (PySpark)

from delta.tables import DeltaTable
from pyspark.sql import functions as F
 
# Bronze → Silver: limpar e deduplciar pedidos
bronze_df = spark.read.format("delta").load("s3://lake/bronze/erp/pedidos/")
 
silver_df = (
    bronze_df
    .dropDuplicates(["pedido_id"])
    .filter(F.col("valor_total") > 0)
    .withColumn("data_pedido", F.to_date("data_pedido_str", "yyyy-MM-dd"))
    .select("pedido_id", "cliente_id", "data_pedido", "valor_total", "status")
)
 
silver_df.write.format("delta").mode("overwrite").save("s3://lake/silver/pedidos/")
 
# Silver → Gold: KPI de receita diária
gold_df = (
    silver_df
    .filter(F.col("status") == "concluido")
    .groupBy("data_pedido")
    .agg(
        F.sum("valor_total").alias("receita_total"),
        F.count("pedido_id").alias("qtd_pedidos")
    )
)
 
gold_df.write.format("delta").mode("overwrite").save("s3://lake/gold/kpis_diarios/")

Por que usar

  • Reprocessamento seguro: Bronze garante que dados brutos sempre estão disponíveis
  • Qualidade incremental: cada camada adiciona confiança, rastreável por linhagem
  • Flexibilidade de consumo: Silver para exploração ad-hoc, Gold para dashboards de produção
  • Separação de responsabilidades: times diferentes podem ser donos de camadas diferentes

Ver também: data-lake-lakehouse | pipeline-de-dados | formatos-de-arquivo-datalake | engenharia-de-dados | databricks | databricks-lakeflow-pipelines | mermaid-diagrams