Un database che gestisce ordini, fatture e magazzino è progettato per fare bene una cosa: registrare tante piccole operazioni, velocemente e senza errori. Quando qualcuno chiede «il fatturato per regione e categoria degli ultimi tre anni, confrontato mese per mese», quello stesso database fatica, e mentre fatica rallenta il lavoro di chi sta inserendo ordini. Non è un difetto: sono due mestieri diversi, che richiedono strutture diverse.
Due tipi di carico
OLTP (Online Transaction Processing) è il carico dei sistemi operativi: gestionali, e-commerce, applicazioni bancarie. Le caratteristiche tipiche:
- moltissime operazioni brevi, ciascuna su poche righe;
- letture e scritture mescolate;
- molti utenti contemporanei;
- schema normalizzato, per evitare incoerenze negli aggiornamenti;
- interesse per lo stato attuale: la giacenza di oggi, l'indirizzo attuale del cliente.
OLAP (Online Analytical Processing) è il carico dell'analisi: report, cruscotti, studi sull'andamento. Le caratteristiche sono quasi opposte:
- poche query, ma ciascuna legge milioni di righe;
- quasi solo letture, con caricamenti periodici di dati nuovi;
- pochi utenti, di solito analisti e responsabili;
- interesse per la storia: come è cambiato qualcosa nel tempo.
Eseguire query analitiche pesanti sul database operativo ha due conseguenze: le query sono lente, perché lo schema normalizzato richiede molte JOIN, e rallentano le operazioni quotidiane, perché consumano le stesse risorse.
Il data warehouse
Un data warehouse è un database separato, alimentato con i dati dei sistemi operativi e organizzato per l'analisi. Spesso raccoglie dati da più fonti: il gestionale, l'e-commerce, il CRM, i fogli di calcolo del reparto commerciale, riconciliandoli in un'unica struttura coerente.
Il processo che porta i dati dalle fonti al warehouse si chiama tradizionalmente ETL: estrazione, trasformazione, caricamento. Oggi si usa spesso anche la variante ELT, in cui i dati vengono caricati quasi grezzi e trasformati dentro il warehouse stesso, sfruttandone la potenza di calcolo.
Lo schema a stella
La struttura più diffusa nei data warehouse è lo schema a stella, descritto in modo sistematico da Ralph Kimball nei suoi testi sulla modellazione dimensionale. Al centro c'è una tabella dei fatti, intorno le tabelle delle dimensioni.
La tabella dei fatti
Contiene gli eventi misurabili, uno per riga, al livello di dettaglio scelto. Per le vendite, una riga può essere una riga di scontrino o di fattura. Le colonne sono di due tipi: chiavi verso le dimensioni e misure numeriche.
CREATE TABLE fatti_vendite (
chiave_data INTEGER NOT NULL REFERENCES dim_data,
chiave_prodotto INTEGER NOT NULL REFERENCES dim_prodotto,
chiave_cliente INTEGER NOT NULL REFERENCES dim_cliente,
chiave_negozio INTEGER NOT NULL REFERENCES dim_negozio,
quantita INTEGER NOT NULL,
importo_netto NUMERIC(12,2) NOT NULL,
costo NUMERIC(12,2) NOT NULL
);
La decisione più importante è la grana: che cosa rappresenta esattamente una riga. Va scelta il più dettagliata possibile, perché dai dati dettagliati si ottengono i riepiloghi, ma non il contrario.
Le tabelle delle dimensioni
Descrivono il contesto dei fatti: chi, che cosa, dove, quando. Sono volutamente denormalizzate. La dimensione prodotto contiene in un'unica tabella codice, nome, marca, sottocategoria, categoria e reparto, anche se in un database operativo starebbero in tabelle separate.
La dimensione data merita una nota: invece di calcolare ogni volta mese, trimestre o giorno della settimana, si crea una tabella con una riga per ogni giorno e tutte le sue proprietà già calcolate, compresi i giorni festivi e i periodi aziendali. Le query diventano semplici:
SELECT d.anno, d.trimestre, p.categoria, SUM(f.importo_netto) AS fatturato
FROM fatti_vendite f
JOIN dim_data d ON d.chiave_data = f.chiave_data
JOIN dim_prodotto p ON p.chiave_prodotto = f.chiave_prodotto
WHERE d.anno IN (2024, 2025)
GROUP BY d.anno, d.trimestre, p.categoria;
Ogni JOIN parte dalla tabella dei fatti e arriva a una dimensione: è la forma a stella che dà il nome allo schema.
Il problema della storia: dimensioni che cambiano
Un cliente si trasferisce da Milano a Napoli. Nel database operativo si aggiorna l'indirizzo e basta. Nel data warehouse ci si deve chiedere: le vendite fatte quando abitava a Milano devono risultare a Milano o a Napoli?
Le soluzioni classiche, chiamate slowly changing dimensions, sono principalmente due:
| Tipo | Che cosa si fa | Effetto sui report |
|---|---|---|
| Tipo 1 | Si sovrascrive il valore | Tutta la storia del cliente risulta a Napoli |
| Tipo 2 | Si aggiunge una nuova riga per il cliente, con date di validità | Le vendite passate restano a Milano, le nuove vanno a Napoli |
Il tipo 2 è il motivo per cui le dimensioni hanno una chiave surrogata propria, diversa dal codice cliente del gestionale: lo stesso cliente può avere più righe, una per ogni periodo.
Serve davvero un data warehouse?
Per una piccola attività, spesso basta meno: una replica in sola lettura del database operativo su cui eseguire i report, oppure alcune viste o tabelle di riepilogo aggiornate ogni notte. Il data warehouse diventa necessario quando le fonti sono più di una, la storia va conservata in modo affidabile o le analisi sono così pesanti da disturbare il lavoro quotidiano.
In sintesi
- OLTP registra molte piccole operazioni; OLAP analizza grandi volumi di dati storici.
- Report pesanti sul database operativo sono lenti e rallentano il lavoro quotidiano.
- Lo schema a stella ha una tabella dei fatti con le misure e dimensioni denormalizzate intorno.
- La grana della tabella dei fatti va scelta il più dettagliata possibile.
- Le dimensioni che cambiano nel tempo si gestiscono sovrascrivendo o storicizzando le righe.