Proposta de site feita pela Genesis Innovation · conteúdo do LinkedIn de Daniel Santos

Pular para o conteúdo
Daniel Santos

Wiki Arquitetura e modelagem

Arquitetura medalhão (bronze, silver, gold)

Três camadas de qualidade crescente. Bronze guarda como chegou, silver limpa e padroniza, gold responde perguntas de negócio.

A arquitetura medalhão organiza o lakehouse em camadas, e cada camada tem um contrato.

  • Bronze: o dado como chegou da fonte (JSON, CSV, CDC), com metadados de ingestão (quando, de onde). Nada é descartado: se a regra da silver estiver errada, dá para reprocessar daqui.
  • Silver: limpo e conformado. Tipos certos, duplicados removidos, chaves válidas, nomes padronizados. É onde regras de qualidade barram ou separam o que não presta.
  • Gold: agregado e modelado para quem consome: métricas de negócio, tabelas de dimensão e fato, o que alimenta Power BI e relatórios.

As três camadas, em SQL que roda aqui

A tabela eventos faz o papel de bronze (veio com um evento repetido). A silver deduplica e só aceita evento de pedido que existe. A gold responde "quantos pedidos foram pagos por dia".

SQL · SQLite
CREATE VIEW silver_eventos AS
SELECT DISTINCT e.id_evento, e.pedido_id, e.tipo, e.ts
FROM eventos e
WHERE EXISTS (SELECT 1 FROM pedidos p WHERE p.id = e.pedido_id);

CREATE VIEW gold_pagamentos_por_dia AS
SELECT date(ts) AS dia, COUNT(*) AS pagamentos
FROM silver_eventos
WHERE tipo = 'pago'
GROUP BY date(ts);

SELECT (SELECT COUNT(*) FROM eventos) AS bronze,
       (SELECT COUNT(*) FROM silver_eventos) AS silver,
       (SELECT SUM(pagamentos) FROM gold_pagamentos_por_dia) AS gold_pagos;

Saída

bronze | silver | gold_pagos
------ | ------ | ----------
7      | 6      | 2

O que não fazer

  • Ler da bronze no relatório "porque está mais atualizada": o relatório herda todo o lixo.
  • Silver que já agrega: aí não há onde reaproveitar o dado limpo e detalhado para outra pergunta.
  • Corrigir dado na gold à mão: a correção some na próxima carga. A regra mora na silver, no código.

No Databricks

Cada camada costuma ser um schema (ou catálogo) no Unity Catalog, com permissões diferentes: engenharia escreve em todas, analistas leem só a gold. A carga entre camadas é um job (ou um pipeline declarativo) com uma tarefa por etapa.

PySparkPrecisa de um cluster Spark: não roda aqui.
bronze = spark.readStream.table("bronze.eventos")
silver = (bronze
    .dropDuplicates(["id_evento"])
    .where("pedido_id IS NOT NULL"))
(silver.writeStream
    .option("checkpointLocation", "/Volumes/lakehouse/silver/_checkpoints/eventos")
    .toTable("silver.eventos"))

Fontes

Conhecimento compartilhado pela Genesis Innovation.