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