Vai al contenuto principale
Layering dbt - immagine ufficiale della lezione su GinnyTech, creata da AD

'Layering: staging, intermediate, marts'

Layering: staging, intermediate, marts. Lezione sul design a strati dei modelli dbt.

AD
Creato da Andrii Dyshkantiuk
Lezione 161 / 216 Livello: Avanzato Durata: 18 min Prerequisiti: 1

Cosa imparerai

  • Comprendere il problema analitico e il contesto decisionale
  • Applicare esempi, metriche e controlli a casi reali

Layering: staging, intermediate, marts

Un warehouse diventa fragile quando ogni query pulisce, unisce e interpreta i dati a modo suo. Layering: staging, intermediate, marts introduce una disciplina semplice: separare normalizzazione, logica riusabile e prodotti dati finali, così ogni passaggio ha un proprietario e un livello di astrazione.

Una scena da cui partire

Leggi la lezione come architettura della fiducia. Il layering non serve a moltiplicare file, ma a rendere visibile dove nasce un dato, dove viene arricchito e dove diventa metrica per il business.

  • Contesto: Quale decisione rende utile il concetto?
  • Metodo: Quale conflitto tra team o metriche devi anticipare?
  • Applicazione: Quale frase useresti per spiegarlo in riunione?

Perché tre layer (e non due, e non quattro)

Il pattern a tre layer di dbt è emerso per convergenza nella community intorno al 2020, non per dogma ma per efficacia empirica. Ogni layer ha una responsabilità precisa e NON invade quella degli altri:

Layer 1 — Staging (stg_)

Responsabilità: leggere i dati grezzi e applicare minime trasformazioni di pulizia.

  • 1:1 con le tabelle sorgente. stg_stripe__payments riflette la tabella payments di Stripe, colonna per colonna.
  • Rinominare colonne per coerenza (es. createdcreated_at, idpayment_id).
  • Cast dei tipi (es. amount_centsamount_eur dividendo per 100 e castando a numeric).
  • Flitri di righe tecnicamente invalide, mai filtri di business (es. rimuovi righe con id IS NULL, ma NON filtrare status = 'live' — quello è business logic, va in intermediate).

Cosa NON fare in staging: JOIN, aggregazioni, CASE WHEN di business, subquery. Se stai unendo due tabelle in staging, stai sbagliando layer.

Layer 2 — Intermediate (int_)

Responsabilità: trasformazioni di business complesse. È il layer più importante e il meno capito.

  • JOIN tra modelli staging per creare entità di business (es. int_orders_with_customers unisce stg_shopify__orders e stg_shopify__customers).
  • Logica di business centralizzata: CASE WHEN status = 'completed' AND refunded_at IS NULL THEN 'net_revenue' ELSE 0 END vive QUI, non nei marts e non nelle query ad-hoc.
  • Aggregazioni intermedie: int_daily_revenue_by_country pre-calcola metriche che servono a più marts.
  • Flag e segmentazioni: is_new_customer, customer_lifecycle_stage, acquisition_cohort.

Regola: se una logica di business viene usata da più di un team, DEVE stare in intermediate. Non nei marts, non nelle query ad-hoc.

Layer 3 — Marts (mrt_ o nomi di dominio)

Responsabilità: dataset pronti per il consumo da parte di strumenti BI e analyst.

  • Organizzati per dominio di business: mrt_marketing__campaign_performance, mrt_product__feature_adoption, mrt_finance__monthly_pnl.
  • Query semplici: i marts fanno SELECT * FROM int_... con al massimo un filtro finale o un’ultima aggregazione.
  • Denormalizzati per performance di lettura: il BI tool vuole una tabella piatta, non 5 join.

Se un mart contiene logica di business complessa (CASE WHEN annidati, subquery, window function), quella logica andava in intermediate.

L’errore più costoso: confondere il layer

L’errore classico è mettere la logica di business nei marts o (peggio) nelle query ad-hoc degli analyst. Questo crea il “shadow schema”: ogni analyst ha la propria versione della stessa logica, non testata e non documentata. Quando la logica cambia (es. nuova definizione di churn), va aggiornata in 15 posti invece che in uno.

Esempio concreto: definizione di “Monthly Active User” (MAU)

Versione senza layering: ogni team scrive la propria query.

-- Team Marketing
SELECT COUNT(DISTINCT user_id) WHERE last_login > CURRENT_DATE - 30
-- Team Product
SELECT COUNT(DISTINCT user_id) WHERE event_type = 'app_open' AND event_date > '2024-01-01'
-- Team Finance
SELECT COUNT(DISTINCT user_id) FROM subscriptions WHERE status = 'active'

Versione con layering:

-- Staging: stg_app__events — 1:1 con la tabella eventi grezza
-- Intermediate: int_user_activity_flags
SELECT user_id, event_date,
  CASE WHEN event_date > CURRENT_DATE - 30 THEN 1 ELSE 0 END AS is_active_30d
-- Marts: mrt_metrics__mau
SELECT DATE_TRUNC('month', event_date) AS month,
  COUNT(DISTINCT CASE WHEN is_active_30d = 1 THEN user_id END) AS mau

Caso reale: il refactoring di una media company

Una media company europea con 30M MAU aveva 200+ modelli dbt, tutti marts. La struttura piatta rendeva impossibile capire le dipendenze. Il team di analytics engineering (4 persone) eseguì un refactoring in tre fasi:

  1. Mappatura delle dipendenze (1 settimana): usando dbt docs e il DAG, identificarono i modelli usati da più marts.

  2. Estrazione in intermediate (3 settimane): per ogni logica duplicata, crearono un modello intermediate e aggiornarono i marts a referenziarlo. Zero cambi funzionali, solo riorganizzazione.

  3. Test e CI enforcement (1 settimana): aggiunsero test automatici su tutti i modelli intermediate + una regola CI che rifiutava PR con modelli marts che contenevano CASE WHEN di business (doveva essere in intermediate).

Il costo totale fu di 5 settimane-uomo. Il beneficio, documentato internamente:

  • Il tempo di onboarding per nuovi analyst scese da 8 settimane a 3
  • Un cambiamento nella definizione di “utente attivo” (da 30 a 28 giorni) richiese 15 minuti e zero errori (prima: 3 giorni di lavoro di 5 persone, con bug)
  • Il team finance scoprì di aver usato una definizione errata di MRR per 6 mesi (il modello intermediate rese evidente la discrepanza con Stripe)

Convenzioni di naming

La community dbt ha convergito su queste convenzioni, e adottarle ti fa risparmiare ore di discussione:

stg_[source]__[table_name]     → stg_stripe__payments
int_[description]               → int_daily_customer_revenue
mrt_[domain]__[description]     → mrt_marketing__campaign_performance

Sempre plurale per le tabelle che rappresentano collezioni di entità (payments, users), singolare per entity dimension (date_spine, country_codes). Niente abbreviazioni criptiche: int_daily_cust_rev è ambiguo tra 3 mesi; int_daily_customer_revenue no.


Riferimenti:

  • dbt Labs. (2024). “Best practice guides: How we structure our dbt projects.” dbt Developer Hub.
  • Hughes, C. (2022). “The Three-Layer Model: Staging, Intermediate, Marts.” dbt Developer Blog.
  • Kimball, R. & Ross, M. (2013). The Data Warehouse Toolkit, 3rd ed. Wiley.

Controllo di qualità

Prima di usare layering: staging, intermediate, marts in una decisione, controlla sempre completezza, duplicati, timezone, definizioni cambiate e segmenti esclusi. Molte analisi apparentemente sofisticate falliscono perché il dato di partenza misura un comportamento diverso da quello che il team crede di osservare.

Interpretazione per segmenti

La media aggregata è solo il punto di partenza. Segmenta per canale, coorte, piano, paese, device e maturità dell’utente. Se due segmenti si muovono in direzioni opposte, la media non rappresenta nessuno dei due e può portare a una decisione sbagliata.

Decisione operativa

Ogni analisi deve terminare con una scelta possibile: continuare, fermare, iterare, investire, rimuovere o approfondire. Se layering: staging, intermediate, marts non cambia una decisione, probabilmente manca ancora il collegamento tra metrica e azione.

Problema reale

Nel dominio di analytics engineering, ‘Layering: staging, intermediate, marts’ serve a risolvere questo problema: trasformare dati grezzi in modelli testati, documentati e riusabili dal business. La lezione non va trattata come teoria isolata, ma come un modo per migliorare una scelta concreta con dati, assunzioni esplicite e controlli minimi.

Obiettivo operativo: Comprendere il problema analitico e il contesto decisionale; Applicare esempi, metriche e controlli a casi reali. Se alla fine non sai indicare quale decisione cambia, quale dato osservi e quale errore vuoi evitare, la lezione non è ancora diventata competenza applicata.

Modello concettuale

FaseCosa chiarireOutput
DomandaQuale scelta reale deve migliorare?Decisione da prendere
MisuraQuale segnale osservabile rappresenta il problema?Metrica o dato sorgente
ControlloQuale baseline rende il risultato interpretabile?Confronto credibile
AzioneChe cosa cambia dopo l’analisi?Prossimo passo operativo

Il modello concettuale è intenzionalmente semplice: decisione, dato, controllo, azione. Ogni approfondimento tecnico deve rafforzare almeno uno di questi quattro punti.

Formalizzazione rigorosa

Per rendere ‘Layering: staging, intermediate, marts’ analizzabile, definisci prima l’unità di lavoro: source, model, test, mart, metrica o esposizione. Poi collega questa unità a una metrica osservabile: freshness, lineage, test coverage, costo modello e fiducia stakeholder. Infine dichiara la decisione attesa: modello dbt, semantic layer, contratto, test o pipeline di release.

ElementoSpecifica richiesta
Unità di analisisource, model, test, mart, metrica o esposizione
Segnale principalefreshness, lineage, test coverage, costo modello e fiducia stakeholder
BaselinePeriodo precedente, gruppo comparabile, benchmark o scenario controfattuale
Decisionemodello dbt, semantic layer, contratto, test o pipeline di release
RischioScambiare un numero disponibile per una prova sufficiente

La formalizzazione e solida quando un altro analista può riprodurre la logica, criticare le assunzioni e ottenere la stessa decisione partendo dagli stessi dati.

Esempio o caso studio

Una metrica di retention viene calcolata direttamente da eventi grezzi in tre dashboard diverse. Applicare layering significa spostare pulizia in staging, logica sessione in intermediate e la metrica finale in un mart, riducendo ambiguità e duplicazione.

Evidenza osservataLettura prudenteAzione consigliata
Il numero miglioraPotrebbe essere effetto reale o variazione normaleCercare confronto e segmento
Un segmento cambia più degli altriLa media aggregata nasconde una differenzaSeparare coorti o casi d’uso
Il costo cresce insieme al risultatoL’impatto va letto sul margineStimare trade-off e sostenibilità

Lab / esercizio

Livello base

Scrivi una scheda di una pagina per ‘Layering: staging, intermediate, marts’: decisione da supportare, metrica primaria, baseline, rischio principale e azione se il segnale e confermato.

Livello intermedio

Costruisci una tabella con tre segmenti, periodi o scenari. Per ciascuno indica cosa cambia, quale spiegazione alternativa e plausibile e quale controllo useresti prima di raccomandare un azione.

Livello research-grade

Prepara un decision memo: ipotesi, dati richiesti, criteri di esclusione, controlli di qualità, soglia decisionale, rischio residuo e piano di monitoraggio dopo la decisione.

Dataset e materiali consigliati

Usa dbt, warehouse, sorgenti CRM, eventi, marts, semantic layer e lineage. Se non hai accesso a dati reali, crea un dataset sintetico con almeno 200 righe, una dimensione temporale, una dimensione segmento e una metrica di outcome.

Errore tipico da evitare

L’errore più comune e usare ‘Layering: staging, intermediate, marts’ come etichetta invece che come processo. Succede quando il team mostra un grafico senza decisione, una metrica senza baseline, o una conclusione senza indicare quale assunzione potrebbe invalidarla.

La domanda di controllo è: se questo risultato fosse instabile, quale scelta sbaglierei? Se la risposta non è concreta, manca ancora il collegamento tra analisi e azione.

Quiz o checkpoint

  1. Quale decisione concreta dovrebbe migliorare questa lezione?
  2. Quale unità di analisi rende il problema misurabile?
  3. Quale baseline useresti per evitare una lettura ingenua?
  4. Quale errore tipico potrebbe cambiare la conclusione?
  5. Quale output consegneresti a uno stakeholder non tecnico?

Riepilogo operativo

‘Layering: staging, intermediate, marts’ diventa utile quando produce una decisione più chiara, non quando aggiunge terminologia. Usa il framework problema, modello, formalizzazione, esempio, lab e checkpoint per trasformare la lezione in pratica verificabile. Categoria: Decisione. Difficoltà: advanced. Tempo stimato: 18 min.