Guida piattaforma dati

Medallion Architecture

Bronze, Silver, Gold: il pattern che ti permette di ingestare dati grezzi velocemente, pulirli a step e servire dataset pronti per il business. Questa guida mostra come applicarlo senza over-engineering.

22 min di letturaPer data & platform engineersCon esempi di codice

1. Cos’è la Medallion Architecture?

Medallion Architecture è un pattern che organizza il lakehouse in tre layer progressivi: Bronze (grezzo), Silver (pulito) e Gold (pronto per il business). Ogni layer aumenta la qualità dei dati e li avvicina al valore.

L’idea di base

Bronze

Grezzo, come arriva

Silver

Pulito, conforme

Gold

Pronto per il business

Perché non pulire una volta sola?

Perché i requisiti cambiano. Conservare il grezzo in Bronze permette il reprocessing quando la logica evolve. Chi salta Bronze deve spesso re-ingestare quando qualcuno chiede “i dati prima di quel filtro”.

Quando usare la Medallion Architecture:

Molte sorgenti dati

Quando ingestisci 10+ sorgenti con formati, schemi e qualità diversi.

Consumatori diversi

Quando i data scientist vogliono il grezzo, gli analisti dati puliti e i dashboard aggregati.

Requisiti in evoluzione

Quando la logica di business cambia spesso e devi rielaborare lo storico.

Compliance

Quando servono audit trail, lineage e prova di come erano i dati in ogni momento.

Dalla pratica

Non conta il nome, ma il principio: non perdere il grezzo, migliora la qualità a step, servi l’astrazione giusta al consumatore giusto. Puoi chiamare i layer “raw/staging/marts” o “landing/curated/consumption” – il pattern è ciò che conta.

2. Le tre layer spiegate

Ogni layer ha uno scopo, un owner e un livello di qualità. Questo modello mentale rende efficace la Medallion.

LayerScopoQualitàConsumatori
🥉 BronzeAtterrare il grezzo esattamente com’èNessuna – tenere tuttoData engineer, debug
🥈 SilverPulire, deduplicare, rendere conformi gli schemiValidato, tipizzato, consistenteData scientist, analisti avanzati
🥇 GoldAggregati e metriche di businessApprovato business, documentatoDashboard, report, applicazioni

Principi chiave per ogni transizione:

🥉→🥈

Da Bronze a Silver

Pulire e conformare

Rimuovere duplicati, castare tipi, applicare lo schema, filtrare record invalidi, standardizzare formati (date, valute, codici).

🥈→🥇

Da Silver a Gold

Aggregare e arricchire

Fare join delle tabelle, calcolare metriche di business, applicare logica, creare modelli dimensionali, ottimizzare per i pattern di query.

Pro tip

Non saltare Silver

È allettante passare da Bronze a Gold, ma Silver è dove vive la qualità. Senza Silver, la pulizia viene duplicata in ogni tabella Gold e i cambi diventano costosi e rischiosi.

3. Approfondimento Bronze

Bronze è il tuo “data lake” puro: tutto atterra qui esattamente come arriva. L’obiettivo è durabilità e tracciabilità, non pulizia.

Cosa deve avere Bronze

  • • Dati grezzi così come arrivano (JSON, CSV, Parquet)
  • • Metadati di ingestion (timestamp, file sorgente, batch ID)
  • • Scritture append-only (mai update/delete)
  • • Partizionamento per data di ingestion
  • • Retention lunga (mesi o anni)

Cosa non deve avere Bronze

  • • Enforcement di schema (lascia entrare il “cattivo”)
  • • Trasformazioni
  • • Logica di deduplicazione
  • • Logica di business o calcoli
  • • Accesso per utenti business

Struttura di una tabella Bronze:

Esempio: schema tabella Bronze orders

-- Bronze: raw_orders
CREATE TABLE bronze.raw_orders (
  -- Ingestion metadata
  _ingested_at      TIMESTAMP,
  _source_file      STRING,
  _batch_id         STRING,
  
  -- Raw payload (store as-is)
  raw_payload       STRING,  -- JSON string, unparsed
  
  -- Or if structured:
  order_id          STRING,  -- Not validated yet
  customer_id       STRING,
  order_date        STRING,  -- Could be any format
  amount            STRING,  -- Could have currency symbols
  status            STRING
)
PARTITIONED BY (_ingested_at::DATE)

Aggiungi metadati di ingestion a ogni record

Timestamp, file sorgente, batch ID. Servono per debug e reprocessing.

Usa scritture append-only

Mai UPDATE o DELETE in Bronze. Una correzione è un nuovo record con un nuovo timestamp.

Partiziona per data di ingestion

Facilita il reprocessing di intervalli specifici e la gestione della retention.

Tienilo economico

Usa formati compressi (Parquet, ORC) e storage a freddo per le partizioni vecchie.

4. Approfondimento Silver

Silver è dove avviene il lavoro vero. È la tua fonte di verità enterprise per dati puliti e validati.

Responsabilità del layer Silver:

1

Enforcement di schema

Castare tipi, imporre NOT NULL, validare i formati. I record invalidi vanno in una tabella di quarantena.

2

Deduplicazione

Rimuovere i duplicati. Usare chiavi di business + timestamp per mantenere la versione più recente.

3

Standardizzazione

Normalizzare date in ISO, valute in base, codici in valori standard.

4

Controlli di qualità

Test automatici: percentuali di null, unicità, integrità referenziale, range di valori.

Esempio: trasformazione Silver orders (dbt)

-- models/silver/orders.sql
WITH source AS (
  SELECT * FROM {{ source('bronze', 'raw_orders') }}
  WHERE _ingested_at >= CURRENT_DATE - INTERVAL '7 days'
),

deduplicated AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY order_id 
      ORDER BY _ingested_at DESC
    ) as row_num
  FROM source
),

cleaned AS (
  SELECT
    -- Cast and validate types
    CAST(order_id AS BIGINT) AS order_id,
    CAST(customer_id AS BIGINT) AS customer_id,
    
    -- Standardize date format
    TO_DATE(order_date, 'YYYY-MM-DD') AS order_date,
    
    -- Clean amount (remove currency symbols)
    CAST(REGEXP_REPLACE(amount, '[^0-9.]', '') AS DECIMAL(10,2)) AS amount,
    
    -- Normalize status to uppercase
    UPPER(TRIM(status)) AS status,
    
    -- Keep lineage
    _ingested_at,
    _batch_id
  FROM deduplicated
  WHERE row_num = 1
    AND order_id IS NOT NULL
)

SELECT * FROM cleaned

Dalla pratica

Silver è dove molti team investono troppo poco. Corrono verso Gold e duplicano la pulizia ovunque. Investi in Silver: ripaga su ogni modello a valle.

5. Approfondimento Gold

Gold è dove vive il valore di business. Sono le tabelle realmente interrogate dagli stakeholder. Pensa a modelli dimensionali, metriche e aggregati per use case.

Pattern tipici in Gold:

Modelli dimensionali (star schema)

Tabelle di fatti (eventi, transazioni) circondate da dimensioni (clienti, prodotti, tempo). Ottimizzate per BI e query ad hoc.

Esempio:

fact_orders ← dim_customers, dim_products, dim_date

Metriche pre-aggregate

Rollup giornalieri/settimanali/mensili per dashboard. Query più veloci, costi minori.

Esempio:

daily_revenue_by_region, weekly_active_users, monthly_churn_rates

Feature table (ML)

Feature pre-computate per modelli di machine learning. Point-in-time corrette, versionate.

Esempio:

customer_features, product_embeddings, user_activity_signals

Esempio: tabella di fatti Gold (dbt)

-- models/gold/fact_orders.sql
WITH orders AS (
  SELECT * FROM {{ ref('silver_orders') }}
),

customers AS (
  SELECT * FROM {{ ref('dim_customers') }}
),

products AS (
  SELECT * FROM {{ ref('dim_products') }}
)

SELECT
  -- Surrogate key
  {{ dbt_utils.generate_surrogate_key(['o.order_id']) }} AS order_key,
  
  -- Foreign keys to dimensions
  c.customer_key,
  p.product_key,
  d.date_key,
  
  -- Degenerate dimensions
  o.order_id,
  o.status,
  
  -- Measures
  o.quantity,
  o.unit_price,
  o.quantity * o.unit_price AS line_total,
  o.discount_amount,
  
  -- Audit columns
  o._ingested_at AS source_loaded_at,
  CURRENT_TIMESTAMP AS dbt_loaded_at

FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id
LEFT JOIN products p ON o.product_id = p.product_id
LEFT JOIN {{ ref('dim_date') }} d ON o.order_date = d.date_day

Principio Gold

Ottimizza per le query

Partiziona sulle colonne più filtrate (data, regione). Cluster sulle chiavi di join.

Principio Gold

Documenta la logica

Ogni tabella Gold deve avere definizioni chiare di metriche e business logic.

Principio Gold

Versiona con attenzione

I cambi su Gold possono rompere dashboard. Usa versioning semantico o alias.

6. Pattern di implementazione

Medallion funziona su qualsiasi piattaforma moderna. Ecco come realizzarla con gli stack più comuni.

PiattaformaBronzeSilver/GoldFormato
DatabricksUnity CatalogDelta Lake + dbtDelta
SnowflakeDatabase RAWdbt + SnowflakeTabelle native
BigQueryDataset raw_dbt + BQTabelle native
AWS (Open)S3 + GlueSpark + dbtIceberg/Hudi

Struttura cartelle/database:

# Convenzione tipica
catalog/
├── bronze/
│   ├── raw_orders
│   ├── raw_customers
│   ├── raw_products
│   └── raw_events
├── silver/
│   ├── orders           # Ordini puliti
│   ├── customers        # Clienti puliti
│   ├── products         # Prodotti puliti
│   └── events           # Eventi puliti
├── gold/
│   ├── dim_customers    # Dimensione: clienti
│   ├── dim_products     # Dimensione: prodotti
│   ├── dim_date         # Dimensione: data
│   ├── fact_orders      # Fatti: ordini
│   └── agg_daily_sales  # Aggregato: vendite giornaliere
└── quarantine/
    ├── orders_failed    # Record falliti
    └── events_failed

Pro tip

Usa database/schemi separati

Non limitarti ai prefissi (raw_, silver_, gold_). Usa database o schemi diversi per applicare permessi, policy di storage e retention specifiche per layer.

7. Checklist best practice

Mai cancellare in Bronze

Solo append. Una correzione = un nuovo record. Bronze è la traccia di audit.

Investi forte in Silver

Qui vive la qualità. Deduplica, enforcement di schema e standardizzazione devono essere solidi.

Mantieni Gold semplice

Le tabelle Gold devono essere facili da interrogare. Pre-join, pre-aggregazioni, ottimizzate per il consumatore.

Documenta tutto in Gold

Ogni tabella Gold deve avere: owner, descrizione, definizioni colonne, frequenza, SLA.

Elabora in modo incrementale

Processa solo dati nuovi/cambiati. I full refresh sono costosi su larga scala.

Metti i record invalidi in quarantena

Non eliminare silenziosamente. Invia a tabelle di quarantena per analisi.

Testa a ogni layer

Controlli DQ Bronze → Silver (schema), Silver → Gold (regole di business), Gold (metriche).

Controlla l’accesso per layer

Bronze: solo data engineer. Silver: team data. Gold: utenti business e dashboard.

Dalla pratica

I team che faticano con la Medallion la trattano come una migrazione una tantum invece che un’architettura continua. Ogni layer necessita di ownership, manutenzione e miglioramenti costanti.

8. Domande frequenti

Che cos’è la Medallion Architecture?

Un pattern che organizza i dati in tre layer: Bronze (grezzo), Silver (pulito e conforme) e Gold (aggregati di business). Migliora progressivamente la qualità nel lakehouse.

Qual è la differenza tra Bronze, Silver e Gold?

Bronze: dati grezzi. Silver: dati puliti, deduplicati, conformi. Gold: aggregati e metriche per dashboard e modelli ML.

Quando usare la Medallion Architecture?

Quando hai più sorgenti, devi migliorare la qualità a step, supportare batch/streaming o servire diversi consumatori.

È solo per Databricks?

No. Funziona su Snowflake, BigQuery, Redshift o stack open source con Delta Lake, Apache Iceberg o Apache Hudi. Grezzo → Pulito → Aggregato vale ovunque.

Visualizza la tua Medallion Architecture

Crea diagrammi chiari con i layer Bronze, Silver e Gold. Documenta flussi, trasformazioni e ownership in pochi minuti.