Siamo ora nel mezzo del Modulo 5, il modulo batch. Le lezioni precedenti hanno costruito i componenti: il lake, il warehouse, l’orchestratore, i formati dei file. Questa lezione fa di nuovo zoom indietro e pone una domanda più semplice. Una volta che hai tutto questo macchinario, come organizzi i dati che vi scorrono dentro? Che aspetto hanno i layer, e cosa promette ognuno di essi?
La risposta più comune nel 2026 è una qualche variante della medallion architecture: i dati scorrono attraverso tre layer, ognuno più curato del precedente, e ognuno chiamato come un metallo. Bronze, silver, gold. La nomenclatura è stata coniata da Databricks e il marketing la fa sembrare più nuova di quanto sia, ma il pattern in sé precede il nome di decenni. I negozi più anziani lo chiamavano “raw, staging, curated”, oppure “L0, L1, L2”, oppure “raw, clean, serving”. La disciplina è la stessa: layer espliciti con responsabilità esplicite, e una norma forte contro il lasciare che le preoccupazioni di un layer trapelino in un altro.
Questa lezione è la passeggiata attenta attraverso ciò che ogni layer contiene davvero, perché i confini sono dove sono, e quando questo intero modello è eccessivo.
Il pattern
Tre layer, in ordine di flusso:
- Bronze: ogni evento, ogni cambiamento, ogni record da ogni sorgente, salvato esattamente come è arrivato. Nessuna trasformazione. Nessuna deduplicazione. Nessun filtraggio di qualità. Append-only e immutabile.
- Silver: il layer pulito, conformato, joinabile. I record sono deduplicati, i tipi sono corretti, gli schemi sono applicati, i record sbagliati sono filtrati fuori. Ancora source-shaped (una tabella silver per entità sorgente, all’incirca), ma affidabile.
- Gold: il layer pronto per l’analisi. Tabelle denormalizzate, aggregate, business-shaped e feature store. I mart da cui leggono le dashboard di BI, le pipeline ML, e i consumer downstream.
I dati scorrono in una sola direzione, da bronze verso gold. Ogni layer è costruito dal layer sottostante tramite una pipeline di trasformazione. Se trovi un bug nella logica silver-to-gold, la rilanci da silver. Se trovi un bug nella logica bronze-to-silver, la rilanci da bronze. Bronze stesso non viene mai ri-derivato: è il system of record di ciò che è arrivato, e rieseguire le sorgenti upstream è di solito costoso o impossibile.
flowchart LR
S[Sources: apps, APIs, databases, events]
B[(Bronze: raw, immutable)]
SI[(Silver: cleaned, conformed)]
G[(Gold: business-aggregate, denormalised)]
C[Consumers: BI, ML, exports]
S --> B --> SI --> G --> C
Quel diagramma è l’intera architettura. Le parti interessanti sono le regole che governano cosa appartiene a ciascuna scatola.
Bronze: il record non modificato
Il lavoro completo del layer bronze è preservare, fedelmente e per sempre, i dati che sono entrati. Il contratto è: “se punti a bronze, vedi esattamente quello che la sorgente ci ha mandato, con i timestamp di quando abbiamo ricevuto ciascun record”.
In pratica questo significa:
- Append-only: le tabelle bronze crescono. Le righe esistenti non vengono aggiornate. Se un record cambia upstream, la nuova versione arriva come una nuova riga, non come un update di quella vecchia.
- Schema-on-read dove possibile: il payload della sorgente è salvato come JSON o nei tipi nativi della sorgente, e il parsing più ricco è lasciato a silver. La ragione è che gli schemi delle sorgenti driftano, e bronze non dovrebbe rompersi quando appare un nuovo campo.
- Storage economico: bronze è il più grande dei tre layer e quello consultato meno frequentemente. Vive su object storage (S3, GCS, ADLS) col tier più economico appropriato per accessi occasionali. La compressione è alta.
- Partizionato per ingestion time: tipicamente
ingest_date=2026-01-16, a volte anche per source. Il time-partitioning ti permette di ragionare su cosa è arrivato quando, e ti permette di cancellare o archiviare partizioni vecchie in modo pulito.
La ragione della regola stretta “nessuna trasformazione” è la replayability. Se la logica silver-to-gold ha un bug che ha corrotto le tue dashboard per tre mesi, sistemi la logica e rilanci silver e gold da bronze, e ti riprendi i tre mesi corretti. Se bronze sta silenziosamente trasformando i dati, non puoi farlo: l’input del bug è andato perso. Bronze è l’unico layer che salva una storia che non può essere ricostruita, e quindi deve salvare tutto, anche i record che sospetti siano sbagliati.
L’altra ragione è la auditability. Quando un regolatore, un’investigazione del customer-support, o una review di sicurezza chiede “cosa ci ha mandato davvero la sorgente la mattina del 3”, la risposta è bronze. Silver e gold non lo sono, perché hanno già filtrato e rimodellato i dati.
Silver: il layer affidabile
Silver è il layer che dice “puoi joinare queste tabelle senza preoccuparti”. Concretamente, questo significa che sono successe diverse cose:
- Deduplicazione. Lo stesso record sorgente può essere arrivato due volte in bronze (perché at-least-once delivery, lezione 16). Silver collassa i duplicati per chiave.
- Type casting. La stringa
"2026-01-16T12:00:00Z"diventa un timestamp. La stringa"42"diventa un intero. Ilcustomer_iddel blob JSON diventa una colonna tipata. - Schema enforcement. Le tabelle silver hanno uno schema dichiarato. I record che non corrispondono vengono inviati a una tabella di quarantena per ispezione, non scartati silenziosamente.
- Quality filtering. I record con chiavi primarie null, timestamp impossibili, o valori fuori dai range concordati sono rimossi e loggati.
- Conforming. I codici dei paesi sono normalizzati a ISO-3166. I codici delle valute sono normalizzati a ISO-4217. I customer ID da sorgenti diverse sono mappati al customer ID canonico dove possibile. La stessa entità di business riferita in due modi diventa lo stesso valore in silver.
Silver è ancora per lo più source-shaped. Se le tue sorgenti sono un orders service e un customers service, hai ancora una silver.orders e una silver.customers, non ancora una gold.customer_360 denormalizzata. La forma cambia da payload raw a tabelle pulite, ma i confini delle entità restano all’incirca dove le sorgenti li hanno messi.
Silver è il layer che a data scientist downstream e analisti ad-hoc dovrebbe essere permesso di interrogare. Ottengono tabelle pulite, joinabili, con colonne documentate e tipi prevedibili. Non ottengono le sorprese di bronze (JSON raw, righe duplicate, schema drift) e non hanno ancora le opinioni forti di gold (una particolare aggregazione, una particolare granularità, un particolare set di regole di business cotto dentro).
Gold: la business shape
Gold è dove vive la business logic. Una tabella gold risponde a una domanda specifica che qualcuno nel business pone davvero. “Quanti ordini abbiamo spedito questa settimana, per region, per categoria di prodotto?” “Qual è il lifetime value di ciascun cliente, aggiornato di notte?” “Qual è il feature vector per questo utente, pronto per il modello di raccomandazione?”
Le tabelle gold sono:
- Denormalizzate. L’istinto relazionale (un’entità per tabella, joinata su richiesta) è sbagliato qui. Una tabella gold è una tabella larga per domanda, joinata e aggregata in anticipo.
- Aggregate alla giusta granularità. Una tabella daily-orders-by-region è a una riga per (date, region), non a una riga per ordine. Una tabella user-features è a una riga per utente, con qualunque rolling-window aggregate il modello richieda.
- Ottimizzate per il pattern di query. Partizionate, clusterizzate, ordinate per le dashboard o i modelli che le leggono. Se una dashboard sta per fare scan per
event_datee raggruppare perregion, la tabella gold è partizionata perevent_datee clusterizzata perregion. - Versionate e contract-stable. I consumer downstream (strumenti BI, pipeline ML, export) prendono dipendenze sulle forme delle tabelle gold, e cambiare quelle forme è un breaking change. Le tabelle gold ricevono la stessa disciplina di API-stability che ricevono le API pubbliche.
Di solito non c’è un singolo schema gold. C’è invece gold_finance, gold_marketing, gold_ml_features, ognuno posseduto dal team che lo consuma, ognuno con le sue tabelle ottimizzate per le domande di quel team. Gold è plurale.
Perché tre layer, non due o quattro
Potresti avere solo bronze e gold, e saltare il mezzo. Le persone lo fanno, nei negozi piccoli. Il problema è che gold deve allora fare tutto: pulizia, conforming, deduplicazione, e aggregazione, tutto in una sola trasformazione. La pipeline diventa un groviglio. Le tabelle gold di due team rifanno lo stesso lavoro di pulizia in modi leggermente diversi e silenziosamente non sono d’accordo. Un bug nello step di pulizia appare in alcune tabelle gold e non in altre. La logica di pulizia e la logica di aggregazione sono mischiate insieme nello stesso SQL, e districarle in seguito è doloroso.
Silver risolve questo essendo la superficie di pulizia condivisa. La pulizia avviene una volta, in silver, e ogni tabella gold costruisce su quello. Il confine è la risposta a “dove mi fido dei dati”. Il contratto su silver è “joinabile e pulito”, e gold può fare affidamento su questo senza rifarlo.
Potresti anche avere quattro o cinque layer: una raw landing zone prima di bronze, un layer “platinum” sopra gold, un “feature store” separato in parallelo a gold. Le persone fanno questo e può funzionare. Il costo è che più layer significano più posti dove la stessa logica può vivere in due di loro, e più disaccordi su quale layer possiede quale trasformazione. Tre è il punto giusto per la maggior parte dei team. Aggiungi layer quando il dolore di non averli è reale, non perché la simmetria del diagramma è attraente.
La disciplina: non lasciare trapelare i layer
Il pattern medallion è facile da disegnare e difficile da far rispettare. I due failure mode che vedo più spesso:
Business logic che striscia dentro bronze. Qualcuno scrive un job di ingestion che “ripulisce” lo strano formato di timestamp della sorgente strada facendo, “perché qui è più facile”. Ora bronze non è più un record fedele di ciò che è arrivato. Sei mesi dopo, quando il parser di timestamp si rivela avere un bug, le stringhe originali sono andate. Resisti a questo. Bronze è il pezzo da museo: guarda ma non toccare.
Record raw che trapelano in gold. Qualcuno ha bisogno di una dashboard veloce, fa query direttamente su bronze, e la spedisce. Ora c’è un consumer in forma gold che legge da un layer che non era mai pensato per essere consumer-facing, senza garanzie di qualità, con uno schema drift che silenziosamente romperà la dashboard la prossima volta che la sorgente cambia. Costruisci una rappresentazione silver di ciò che la dashboard richiede e fagliela leggere da lì. La scorciatoia compone interesse.
La disciplina è di solito il formato di tabella del lakehouse (Delta, Iceberg, Hudi) più l’access control: solo la pipeline silver può scrivere sulle tabelle silver, solo la pipeline gold può scrivere sulle tabelle gold, e bronze è read-only dopo l’ingestion. Il formato e i permessi rendono effettivo ciò che il diagramma solo suggerisce.
Quando non fare medallion
Medallion è appropriato quando hai un lake o lakehouse vero, sorgenti multiple, consumer multipli, e una quantità non banale di dati. Se non li hai, i layer sono overhead che non ti compra niente.
Casi in cui un solo layer basta:
- Dataset molto piccoli. Se tutto il tuo “warehouse” è qualche centinaio di megabyte di dati aggiornati di notte in Postgres, basta avere uno schema
staginge uno schemaprod. Il layer bronze aggiunge costo di storage e complessità di pipeline senza alcun beneficio. - OLTP puro. Se non hai affatto un lake, e la tua analitica consiste di una manciata di view materializzate sul database transazionale, non ti serve medallion. Ti servono buone view.
- Sistemi streaming-first. Le pipeline real-time, dove i dati devono fluire dalla sorgente al consumer in pochi secondi, non hanno tempo per tre hop batch. La Kappa architecture (Modulo 6, lezione 47) è una forma del tutto diversa: una sorgente di verità streaming e materializzazioni a partire da essa. Medallion è la forma batch; Kappa è la forma streaming; la lambda architecture è il compromesso infelice.
Il trigger per adottare medallion è di solito il secondo consumer. Non appena due team vogliono interrogare gli stessi dati e uno di loro sta facendo cleanup che anche l’altro dovrebbe fare, hai il problema in forma silver. Non appena tre team vogliono aggregazioni diverse degli stessi dati puliti, hai il problema in forma gold. Costruisci il layer che risolve il dolore che hai davvero, non quello che il diagramma dice che dovresti avere.
La prossima lezione tratta i formati di tabella che rendono possibile tutta questa architettura alla scala del lakehouse: Delta Lake, Apache Iceberg, e Apache Hudi.