Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Informativi
Avanzati
Anno
Accademico
2013/2014
Prof.
Domenico
Beneventano
ESERCIZI Data Warehousing
1
ESERCIZI - PROGETTAZIONE DI UN DW ................................................................................................... 2
1.1
Esercizio: Spedizione ............................................................................................................................. 2
1.1.1
Soluzione .......................................................................................................................................... 4
1.1.2
Variante 1 ....................................................................................................................................... 11
1.1.3
Variante 2 (misura derivata) .......................................................................................................... 11
1.1.4
Variante 3: (schema transazionale)................................................................................................ 12
1.1.5
Soluzioni possibili per la misura NUMERO (conteggio eventi primari)........................................... 14
1.1.6
Soluzioni possibili per la misura COSTO (misura con AVG in schema transazionale) .................. 15
1.2
Esercizio: Dettaglio Ordine .................................................................................................................. 19
1.2.1
Soluzione ........................................................................................................................................ 19
1.3
Esercizio: Biglietto ................................................................................................................................. 22
1.3.1
Soluzione ........................................................................................................................................ 24
1.3.2
Variante .......................................................................................................................................... 26
1.3.3
Variante (dimensione derivante da discretizzazione) .................................................................... 27
1.4
Esercizio : Esame ................................................................................................................................. 29
1.4.1
Soluzione ........................................................................................................................................ 30
1.5
Esercizio: Vendita ................................................................................................................................. 32
1.5.1
Soluzione ........................................................................................................................................ 32
1.6
Esercizio (19/12/2012) .......................................................................................................................... 34
1.7
Esercizio (14/01/2013 ) ......................................................................................................................... 35
1.8
Esercizio (16/04/2013 ) ......................................................................................................................... 36
1.9
Esercizio (10/09/2013 ) ......................................................................................................................... 37
1 ESERCIZI - Progettazione di un DW
Per alcuni esercizi viene anche riportato il codice SQL per provare le soluzioni date. La Fact Table e le
dimension table sono definite come viste nel DBO dato (architettura ad un livello)
(1,1)
MAGAZZINO
(1,N)
IN
STATO
CITTA
(0,N)
CITTA
IN
INDIRIZZO
(1,1)
(1,1)
REPARTO
CLIENTE
REPARTO
DATA(DATA,MESE,ANNO)
DF: MESE ANNO
(0,N)
MAGAZZINO
(1,N)
CITTA(CITTA,REGIONE,STATO)
DF: REGIONE STATO
CLIENTE
DA
ORDINE(ORDINE,CLIENTE:CLIENTE,DATA:DATA)
REPARTO(REPARTO,MAGAZZINO:MAGAZZINO)
MAGAZZINO(MAGAZZINO,CITTA:CITTA)
(1,N)
CLIENTE(CLIENTE,CITTA:CITTA)
DEL
COSTO
(1,1)
PRODOTTO
DETTAGLIO
SPEDIZIONE
(1,1)
SPEDIZIONE(NRIGA,ORDINE:ORDINE,
PRODOTTO,
REPARTO:REPARTO
DATASPEDIZIONE:DATA,
COSTO)
(1,1)
(1,N)
ORDINE
(1,1)
(1,1)
ORDINE
NRIGA
DATA
(0,N)
DATA
SPEDIZIONE
AK : { ORDINE,PRODOTTO,
REPARTO,DATASPEDIZIONE }
DATA
ORDINE
MESE
ANNO
DATA
(0,N)
Esempio di istanza del DBO e corrispondente istanza del fatto (eventi primari)
1.1.1
Soluzione
Progettazione Concettuale
Nella progettazione concettuale occorre riportare uno schema di fatto con tutte le dimensioni richieste e, per
ciascuna dimensione, con tutta la gerarchia derivante dallo schema del DBO.
Albero degli attributi iniziale
REGIONE STATO
MESE ANNO
Si ottiene
CITTA
REGIONE
MAGAZZINO
STATO
SPEDIZIONE
CLIENTE
NUMERO
(C) COSTO (AVG)
NUMERO_ORDINI
DATASPED
MESE
ANNO
PRODOTTO
Progettazione Logica
Nella Progettazione logica viene richiesto di delineare sia lo STAR SCHEMA che lo SNOWFLAKE
SCHEMA; La Fact Table in questi due tipologie di schemi coincide (mentre quelle che cambiano sono
ovviamente le Dimension Table) quindi possiamo riportare la Fact Table una sola volta.
La Fact Table ha la seguente struttura
FACT_TABLE(PRODOTTO,MAGAZZINO,CLIENTE,DATASPED,
NUMERO,COSTO_SUM,COSTO_COUNT, NUMERO_ORDINI)
Come detto in precedenza, dobbiamo chiederci se le due misure
NUMERO= COUNT(*), additiva
COSTO_COUNT = COUNT(COSTO), additiva
sono equivalenti, ovvero se il loro valore coincide. Quindi si dovrebbe controllare se COUNT(*) e
COUNT(COSTO) restituiscono lo stesso valore: la risposta negativa se nel DBO il campo COSTO pu
assumere dei valori NULL, in quanto per definizione un valore NULL viene conteggiato da COUNT(*) ma
non viene conteggiato da COUNT(COSTO). Nei nostri esercizi si suppone il caso generale della presenza di
NULL pertanto nella Fact Table verranno sempre tenute entrambe le misure.
La Fact Table sar quindi
FACT_TABLE(CLIENTE:dtCLIENTE,MAGAZZINO:dtMAGAZZINO,DATASPED:dtDATA,PRODOTT
O,
NUMERO,COSTO_SUM,COSTO_COUNT, NUMERO_ORDINI)
Si noti che la dimensione PRODOTTO degenere, quindi non viene inserita la relativa Dimension Table.
Star Schema
dtDATA(DATA,MESE,ANNO)
dtCLIENTE(CLIENTE,CITTA,REGIONE,STATO)
dtMAGAZZINO(MAGAZZINO,CITTA,REGIONE,STATO)
SnowFlake Schema
dtDATA(DATA,MESE:dtMESE)
dtMESE(MESE,ANNO)
dtCLIENTE(CLIENTE,CITTA:dtCITTA)
dtMAGAZZINO(MAGAZZINO,CITTA:dtCITTA)
dtCITTA(CITTA,REGIONE:dtREGIONE)
dtREGIONE(REGIONE,STATO)
Alimentazione
La query di alimentazione della fact table costituita come segue:
FROM: oltre alla tabella SPEDIZIONE, si deve considerare la tabella REPARTO (che contiene
MAGAZZINO) e la tabella ORDINE (che contiene CLIENTE).
GROUP BY: banale, contiene le dimensioni del fatto
SELECT: oltre alle dimensioni del fatto si riporta il calcolo delle misure sulla base di quanto specificato nel
glossario
CREATE VIEW FACT_TABLE AS
SELECT
SPEDIZIONE.PRODOTTO,
REPARTO.MAGAZZINO,
ORDINE.CLIENTE,
SPEDIZIONE.DATASPEDIZIONE AS DATASPED,
COSTO_SUM =SUM(COSTO),
COSTO_COUNT =COUNT(COSTO),
NUMERO =COUNT(*)
NUMERO_ORDINI =COUNT(DISTINCT ORDINE.ORDINE)
FROM
SPEDIZIONE NATURAL JOIN
REPARTO NATURAL JOIN
ORDINE
GROUP BY
SPEDIZIONE.PRODOTTO,
SPEDIZIONE.DATASPEDIZIONE,
ORDINE.CLIENTE,
REPARTO.MAGAZZINO
Per provare la query, dovendola eseguire su un DBMS che non supporta il NATURAL JOIN:
FROM
SPEDIZIONE JOIN
REPARTO ON REPARTO.REPARTO = SPEDIZIONE.REPARTO JOIN
ORDINE ON ORDINE.ORDINE = SPEDIZIONE.ORDINE
10
1.1.2
Variante 1
Viene richiesto di discutere come cambia laggregabilit della misura NUMERO_ORDINI considerando
come dimensione MESE_ORDINE invece di DATASPED.
Dimensioni: {PRODOTTO,MAGAZZINO,CLIENTE,MESE_ORDINE}
Le FD che riguardano ORDINE sono (ricordiamo che NUMERO_ORDINI=SELECT (DISTINCT ORDINE))
ORDINE CLIENTE
ORDINE MESE_ORDINE
Quindi ora NUMERO_ORDINI aggregabile sia rispetto a CLIENTE che MESE_ORDINE, pertanto
NA: {PRODOTTO,MAGAZZINO }
1.1.3
Viene richiesto di discutere come cambia laggregabilit della misura NUMERO_ORDINI considerando
come dimensione ORDINE invece di CLIENTE.
Dimensioni: {PRODOTTO,MAGAZZINO, ORDINE,DATASPED }
Rispetto allesempio precedente, si usa come dimensione ORDINE al posto di CLIENTE, pertanto il nuovo
fatto ad un maggiore livello di dettaglio. Laspetto principale riguarda la misura
NUMERO_ORDINI=COUNT(DISTINCT ORDINE):
grazie alla presenza della dimensione ORDINE, adesso NUMERO_ORDINI una misura derivata da una
dimensione, quindi non verr inserita nella fact table!
Lo schema di fatto simile a quello precedente: laggiunta dellattributo dimensionale ORDINE fa si che
DATA sia ora un attributo dimensionale in comune tra la dimensione ORDINE (infatti un ORDINE ha una
DATA) e la dimensione DATASPED. Si noti che per questo attributo dimensionale in comune si utilizza il
termine pi generale DATA e non DATA_SPED (altrimenti verrebbe indicato che un ORDINE ha una
DATA_SPED, cosa non vera). Per DATA_SPED deve restare come nome della dimensione, pertanto si
mette tale nome sul arco (come avveniva ad esempio nel caso del Fatto Chiamata discusso sulle dispense).
CITTA
MAGAZZINO
SPEDIZIONE
NUMERO
STATO
REGIONE
ORDINE
CLIENTE
ANNO
PRODOTTO
DATA
SPED
DATA
MESE
11
1.1.4
Nel seguito viene svolto (interamente) questo nuovo caso, mettendo in evidenza come per uno schema di
fatto transazionale sia differente la query di alimentazione della fact table ed il calcolo delle misure, in
particolare quelle aggregate tramite media.
12
Progettazione Concettuale
Lo schema di fatto simile a quello precedente: laggiunta dellattributo dimensionale ORDINE fa si che
DATA sia ora un attributo dimensionale in comune tra la dimensione ORDINE (infatti un ORDINE ha una
DATA) e la dimensione DATASPED. Nel seguito verr discussa la convergenza/condivisione su DATA.
REPARTO
CITTA
MAGAZZINO
SPEDIZIONE
STATO
REGIONE
ORDINE
NUMERO
CLIENTE
ANNO
PRODOTTO
DATA
SPED
DATA
MESE
13
1.1.5
La misura NUMERO nel caso di schema transazionale corrisponde a quanto discusso nel caso di Schemi
di fatto vuoti, ovvero NUMERO una misura che serve per il conteggio degli eventi primari. Come era stato
gi fatto notare e come evidenzieremo nellesempio, il nome Schemi di fatto vuoto deriva dal fatto che in
questo caso una possibile soluzione quella di non inserire esplicitamente nessuna misura nello schema di
fatto per il conteggio degli eventi primari, ovvero non memorizzare nessun valore : questo concetto di non
inserire nessuna misura e non memorizzare nessun valore comporta che nella fact table corrispondente non
ci sia nessun attributo per questa misura. Daltra parte, lo schema di fatto e quindi la fact table possono
contenere altre misure (come capita in questo caso per la misura COSTO)
Prima Soluzione : misura conteggio per il conteggio degli eventi primari
Misure normali
(COUNT) per indicare appunto una misura vuota per il conteggio degli eventi primari
Fact Table
FACT_TABLE(PRODOTTO,REPARTO,ORDINE,DATASPED)
Alimentazione
CREATE VIEW FACT_TABLE AS
SELECT PRODOTTO, REPARTO,ORDINE, DATASPEDIZIONE AS DATASPED
FROM SPEDIZIONE
14
1.1.6
Soluzioni possibili per la misura COSTO (misura con AVG in schema transazionale)
In uno schema transazionale, per una misura quale COSTO che deve essere aggregata tramite media ci
sono due soluzioni possibili
1)
2)
15
Alimentazione
CREATE VIEW FACT_TABLE AS
SELECT PRODOTTO, REPARTO,ORDINE, DATASPEDIZIONE, COSTO AS DATASPED
FROM SPEDIZIONE
Come esempio di utilizzo di questa misura, calcoliamo il pattern {MAGAZZINO_CITTA,CLIENTE_CITTA} e
tutti i suoi sub-pattern nello SNOW-FLAKE schema:
SELECT
M.CITTA
C.CITTA
COSTO =
FROM
<come
AS MAGAZZINO_CITTA,
AS CLIENTE_CITTA,
AVG(COSTO),
prima>
Si pu verificare che il risultato corretto, confrontandolo con quanto ottenuto negli schemi di fatto
precedenti.
Seconda Soluzione : misura calcolata COSTO = COSTO_SUM/COSTO_COUNT
In questo caso abbiamo due misure normali
COSTO_SUM = COSTO, additiva
COSTO_COUNT = COUNT(COSTO), additiva
Che verranno poi usate per il calcolo della misura calcolata COSTO.
In questo caso, essendo lo schema transazionale, gli eventi primari verranno calcolati senza raggruppare e
quindi non ha ovviamente senso definire una misura attraverso un operatore di aggregazione:
in COSTO_COUNT = COUNT(COSTO) stato indicato COUNT corsivato proprio per indicare che
concettualmente devo fare un conteggio ma questo conteggio unitario, cio COSTO_COUNT=1. Di
conseguenza questa misura COSTO_COUNT coincide con la misura NUMERO e pertanto pu essere
definita e calcolata come gi discusso in precedenza: COUNT(*) oppure SUM(1).
Fact Table
FACT_TABLE(PRODOTTO,REPARTO,ORDINE,DATASPED,COSTO_SUM)
Alimentazione
CREATE VIEW FACT_TABLE AS
SELECT PRODOTTO, REPARTO,ORDINE, DATASPEDIZIONE AS DATASPED, COSTO
FROM SPEDIZIONE
Come esempio si calcola il pattern {MAGAZZINO_CITTA,CLIENTE_CITTA} e tutti i suoi sub-pattern nello
SNOW-FLAKE schema utilizzando per COSTO_COUNT le due possibilit
SELECT
M.CITTA AS MAGAZZINO_CITTA,
C.CITTA AS CLIENTE_CITTA,
COSTO = SUM(COSTO_SUM)/ COUNT(*) oppure COSTO = SUM(COSTO_SUM)/
SUM(1)
FROM
<come prima>
Si pu verificare che il risultato corretto, confrontandolo con quanto ottenuto negli schemi di fatto
precedenti.
Le due soluzioni per il calcolo di COSTO come valore medio coincidono nellipotesi che nello schema
operazionale il valore di COSTO non sia NULL; infatti un valore NULL di COSTO non viene considerato,
cio non partecipa al calcolo, nella prima soluzione in quanto, per definizione la funzione AVG viene
calcolata sui valori non nulli. Nella seconda soluzione invece il valore NULL di COSTO viene considerato in
quanto non viene sommato (per definizione anche la funzione SUM sui valori non nulli) ma viene
conteggiato, sia attraverso COUNT(*), in quanto per definizione COUNT(*) conta anche i valori nulli, sia
attraverso SUM(1) .
Modifichiamo la tabella SPEDIZIONE con alcuni NULL su COSTO, quindi verifichiamo la differenza per un
semplice pattern {ORDINE}
16
Nel caso di COSTO come misura calcolata, per considerare che COSTO pu essere nullo e quindi non
deve partecipare alla media, non possiamo usare pi come COSTO_COUNT lespressione SUM(1) (stesso
discorso per lespressione COUNT(*)) ma dobbiamo conteggiare in maniera diversa i valori NULL, pertanto
si inserisce una misura normale COSTO_COUNT che sar 1 se COSTO non NULL, 0 altrimenti.
Fact Table
FACT_TABLE(PRODOTTO,REPARTO,ORDINE,DATASPED,COSTO_SUM,COSTO_COUNT)
Alimentazione
CREATE VIEW FACT_TABLE AS
SELECT PRODOTTO, REPARTO,ORDINE, DATASPEDIZIONE AS DATASPED,
COSTO_SUM=COSTO,
COSTO_COUNT= CASE WHEN COSTO IS NULL THEN 0 ELSE 1 END
FROM SPEDIZIONE
Verifichiamo nellesempio della pagina precedente:
DBO: tabella SPEDIZIONE
17
Codice SQL
Creazione del DBO (verificare, pu non essere completamente aggiornato rispetto allesempio)
CREATE
CREATE
CREATE
CREATE
CREATE
CREATE
CREATE
TABLE
TABLE
TABLE
TABLE
TABLE
TABLE
TABLE
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INT,DATASPEDIZIONE
)
)
)
)
)
)
)
)
)
)
)
)
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
INT,COSTO FLOAT);
1,1,1000,10,10,10
2,1,1000,10,10,21
3,1,1000,10,10,11
4,1,3000,10,10,11
1,2,3000,20,30,11
2,2,3000,30,30,11
3,2,1000,20,10,10
4,2,1000,30,10,11
5,2,1000,20,10,11
1,3,3000,20,10,11
2,3,3000,30,10,21
3,3,3000,20,30,11
18
IN
(1,1)
AZIENDA
STATO
(0,N)
(1,N)
DATA(DATA,MESE,ANNO)
DF: MESE ANNO
CITTA
AZIENDA
INDIRIZZO
DI
(1,1)
(0,N)
ORDINE(ORDINE,CLIENTE:CLIENTE,DATA:DATA)
(1,1)
PREFER
PRODOTTO
PRODOTTO
CITTA(CITTA,REGIONE,STATO)
DF: REGIONE STATO
CITTA
(0,N)
(1,1)
PRODOTTO(PRODOTTO,AZIENDA:AZIENDA)
CLIENTE
(0,N)
(1,N)
AZIENDA(AZIENDA,CITTA:CITTA)
CLIENTE
DA
DEL
COSTO
(1,1)
CLIENTE(CLIENTE,CITTA:CITTA,
PREFER:PRODOTTO)
(1,1)
DETTAGLIO
(1,1)
(1,N)
DETTAGLIO(NRIGA,ORDINE:ORDINE,
PRODOTTO:PRODOTTO,
DATASPEDIZIONE:DATA,
COSTO)
ORDINE
(1,1)
(1,1)
ORDINE
NRIGA
DATA
ORDINE
MESE
ANNO
DATA
(0,N)
DATA
SPEDIZIONE
DATA
(0,N)
Viene richiesto di
A) Progettazione concettuale : Progettazione dello schema di fatto DETTAGLIO con dimensioni
{PRODOTTO,ORDINE,DATASPED} e misure {COSTO,NUMERO} dove
COSTO: il costo medio
NUMERO: il numero complessivo di spedizioni
B) Progettazione logica : Progettazione dello STAR SCHEMA e SNOWFLAKE SCHEMA
C) Alimentazione : Scrivere in SQL lalimentazione della fact-table.
1.2.1
Soluzione
Lo schema di fatto simile a quello del fatto Spedizione seconda variante: lunica aggiunta
lassociazione PREFER (un CLIENTE ha un PRODOTTO preferito) che collega CLIENTE a PRODOTTO.
Questo comporta che lattributo dimensionale PRODOTTO sia ora comune alle due dimensioni ORDINE e
PRODOTTO. In questo caso - a differenza di quanto discusso con DATA e DATA_SPED - non essendoci
ambiguit possiamo usare lo stesso nome PRODOTTO sia per la dimensione che per lattributo comune.
PRODOTTO
AZIENDA
CITTA
DETTAGLIO
REGIONE
NUMERO
(C) COSTO (AVG)
STATO
ORDINE
CLIENTE
ANNO
DATA
SPED
DATA
MESE
Con la nuova associazione PREFER, CITTA raggiungibile anche con il percorso CLIENTE_PRODOTTO.
19
Alimentazione
CREATE VIEW FACT_TABLE AS
SELECT
PRODOTTO, ORDINE, DATASPED
COSTO_SUM =SUM(COSTO),
COSTO_COUNT =COUNT(COSTO),
NUMERO =COUNT(*)
FROM
DETTAGLIO
GROUP BY
PRODOTTO, ORDINE, DATASPED
20
Codice SQL
Creazione del DBO
CREATE
CREATE
CREATE
CREATE
CREATE
CREATE
CREATE
TABLE
TABLE
TABLE
TABLE
TABLE
TABLE
TABLE
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
DETTAGLIO
(
(
(
(
(
(
(
(
(
(
(
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
NRIGA,ORDINE,PRODOTTO,DATASPED,COSTO
)
)
)
)
)
)
)
)
)
)
)
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
SELECT
1,4,10,30,22
2,4,20,30,22
3,4,30,30,22
1,1,10,30,16
2,1,20,20,15
3,1,30,30,13
1,2,10,20,13
2,2,20,30,13
3,2,30,20,12
1,3,10,20,11
2,3,30,30,22
21
22
Esempio di istanza del DBO e corrispondente istanza del fatto (eventi primari)
VOLO
BIGLIETTO
CHECK-IN
Eventi Primari
del Fatto BIGLIETTO
Con dimensioni
{VOLO,NPOSTO }
CREATE
CREATE
CREATE
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
23
1.3.1
Soluzione
Progettazione Concettuale
Per semplicit, si procede effettuando prima il reverse engineering dello schema relazionale
Si inizia da
VOLO(CODVOLO,DATA,RITARDO,COMPAGNIA)
Che corrisponde ad unentit identificata da DATA+CODVOLO.
Quindi BIGLIETTO
BIGLIETTO(POSTO,[CODVOLO,DATA]:VOLO,COSTO )
Identificata da entit VOLO + NPOSTO; infine
CHECK-IN([POSTO,CODVOLO,DATA]: BIGLIETTO,
NCOLLI )
Essendo la foreign key sulla sua primary key: un subset.
NPOSTO
BIGLIETTO
CHECK-IN
NCOLLI
(1,1)
COSTO
DEL
(1,N)
DATA
RITARDO
COMPAGNIA
VOLO
CODVOLO
NPOSTO
BIGLIETTO
(C) COSTO (AVG)
NBC
NB
CODVOLO
VOLO
COMPAGNIA
DATA
RITARDO
Fatto BIGLIETTO(VOLO,NPOSTO,COSTO)
Dimensioni =
{VOLO,NPOSTO}
Granularit: Transazionale (infatti VOLO CODVOLO + VOLO, quindi si ottiene CODVOLO, VOLO,DATA)
Dipendenze funzionale tra le dimensioni: Nessuna
Misure normali
NB=1, additiva
NBC = IF <BIGLIETTO CON CHECK-IN> THEN 1 ELSE 0, additiva
Si noti che a questo punto viene solo indicato, ad alto livello, come calcolare NBC; il calcolo effettivo
verr esplicitato in fase di alimentazione
Misure calcolate
COSTO= COSTO_SUM/COSTO_COUNT
dove COSTO_SUM = SUM(COSTO), additiva
COSTO_COUNT = COUNT(COSTO), additiva
Fact Table
FACT_TABLE(VOLO,NPOSTO,NBC, COSTO_SUM,COSTO_COUNT)
Si noti che sono gi state fatte due scelte progettuali:
1) per la misura NB: non viene introdotta nella Fact Table, verr aggregata tramite COUNT(*)
24
2) per la misura COSTO: lo schema transazionale, si sono due possibilit per definire COSTO
(vedere sezione 1.1.4) , viene scelto di considerare COSTO come misura calcolata
Progettazione Logica
FACT_TABLE(NPOSTO,VOLO:dtVOLO, NBC, COSTO_SUM,COSTO_COUNT)
Star Schema (lo SnowFlake schema coincide con lo star-schema)
dtVOLO(VOLO,DATA,CODVOLO,COMPAGNIA,RITARDO)
Alimentazione
Lo schema transazionale, quindi la vista di alimentazione non deve raggruppare. Si deve calcolare
NBC = IF <BIGLIETTO CON CHECK-IN> THEN 1 ELSE 0, additiva
Per controllare se il BIGLIETTO anche in CHECK-IN : si effettua un left-join
SELECT
NBC=CASE WHEN C.[CODVOLO] IS NULL THEN 0 ELSE 1 END
FROM BIGLIETTO B LEFT JOIN [CHECK-IN] C ON (
B.[DATA]=C.[DATA] AND B.[CODVOLO]=C.[CODVOLO] AND B.[POSTO] =
C.[POSTO])
E importante (anche senza eseguirla effettivamente) sapere che questa query restituisce in output lo stesso
numero di tuple di BIGLIETTO: infatti BIGLIETTO nel lato left del join e BIGLIETTO e CHECK-IN
condividono la chiave. Pertanto se nella select si mette BIGLIETTO.*, NBC ottengo la tabella BIGLIETTO
con in pi la colonna NBC e quindi ho tutto quello che mi serve per calcolare la Fact Table.
CREATE VIEW FACT_TABLE AS
SELECT B.POSTO AS NPOSTO,
VOLO= B.DATA + CODVOLO,
NBC=CASE WHEN C.[CODVOLO] IS NULL THEN 0 ELSE 1 END,
COSTO_SUM=COSTO,
COSTO_COUNT =CASE WHEN COSTO IS NULL THEN 0 ELSE 1 END
FROM BIGLIETTO B LEFT JOIN [CHECK-IN] C ON (
B.[DATA]=C.[DATA] AND B.[CODVOLO]=C.[CODVOLO] AND B.[POSTO]=C.[POSTO])
In realt per effettuare la concatenazione VOLO= B.DATA + CODVOLO occorre convertirli in stringhe
VOLO=CONVERT(CHAR(20),B.DATA) + '__' +CONVERT(CHAR(20),B.CODVOLO) .
Anche se non richiesto dal testo, si riporta lalimentazione della dtVOLO:
CREATE VIEW dtVOLO AS
SELECT
VOLO=CONVERT(CHAR(20),DATA) + '__' +CONVERT(CHAR(20),CODVOLO),
CODVOLO,DATA,COMPAGNIA, RITARDO
FROM VOLO
25
1.3.2
Variante
Fatto: BIGLIETTO(VOLO,POSTO,COSTO)
Dimensioni =
{VOLO,NPOSTO}
Granularit: Transazionale
Dipendenze funzionale tra le dimensioni: Nessuna
Misure normali
NB=COUNT(*), additiva
NBC = SUM(IF <BIGLIETTO CON CHECK-IN> THEN 1 ELSE 0), additiva
NCOLLI = SUM(IF <BIGLIETTO CON CHECK-IN> THEN NCOLLI ELSE 0), additiva
GUADAGNO=COSTO, additiva
Misure calcolate
COSTO= COSTO_SUM/COSTO_COUNT
dove
COSTO_SUM = SUM(COSTO), additiva
COSTO_COUNT = COUNT(COSTO), additiva
Progettazione Logica
Naturalmente GUADAGNO viene calcolata a partire da COSTO_SUM, quindi non serve un altro attributo:
FACT_TABLE(NPOSTO,VOLO:dtVOLO, NBC, COSTO_SUM,COSTO_COUNT,NCOLLI)
Alimentazione: si aggiunge il calcolo della misura normale NCOLLI
NCOLLI=ISNULL(NCOLLI,0)
26
1.3.3
Si considera unaltra variante in cui la precedente dimensione NPOSTO viene discretizzata nellattributo
dimensionale CLASSE in questo modo:
se NPOSTO <= 1 allora PRIMA altrimenti SECONDA
Schema di fatto con dimensioni {VOLO,CLASSE}
e misure {COSTO,NBIGLIETTI,NBIGLIETTI_CHECK-IN,GUADAGNO,NCOLLI}.
GUADAGNO ancora definita come SUM(COSTO)
Esempio di istanza del DBO e corrispondente istanza del fatto (eventi primari)
Eventi Primari
del Fatto BIGLIETTO
BIGLIETTO
CLASSE
Fatto BIGLIETTO(VOLO,POSTO,COSTO)
Dimensioni =
{VOLO,CLASSE}
Granularit: Temporale
Dipendenze funzionale tra le dimensioni: Nessuna
CODVOLO
VOLO
COMPAGNIA
DATA
RITARDO
Misure normali
NB=COUNT(*), additiva
NBC = SUM(IF <BIGLIETTO CON CHECK-IN> THEN 1 ELSE 0), additive
NCOLLI = SUM(IF <BIGLIETTO CON CHECK-IN> THEN NCOLLI ELSE 0), additiva
GUADAGNO : SUM(COSTO), additiva
Misure calcolate
COSTO= COSTO_SUM/COSTO_COUNT dove
COSTO_SUM = SUM(COSTO), additiva
COSTO_COUNT = COUNT(COSTO), additiva
27
Progettazione Logica Star Schema (lo SnowFlake schema coincide con lo star-schema)
FACT_TABLE(CLASSE,VOLO:dtVOLO,NB,NBC,NCOLLI, COSTO_SUM,COSTO_COUNT)
dtVOLO(VOLO,DATA,COMPAGNIA,FASCIA_RITARDO)
Alimentazione: Essendo lo schema temporale, lalimentazione della Fact Table richiede di raggruppare
sulle dimensioni. Per in questo caso entrambe le dimensioni sono calcolate
VOLO = DATA + CODVOLO
CLASSE = IF POSTO <=1 THEN 'PRIMA' ELSE 'SECONDA' END
In SQL il raggruppamento GROUP BY possibile anche su espressioni generiche quindi
CREATE VIEW FACT_TABLE AS
SELECT
VOLO = CONVERT(CHAR(11), B.DATA) + '__' + CONVERT(CHAR(3), B.CODVOLO),
CLASSE = CASE WHEN B.POSTO <=1 THEN 'PRIMA' ELSE 'SECONDA' END,
COSTO_SUM =SUM(COSTO),
COSTO_COUNT=COUNT(COSTO),
NB=COUNT(*),
NBC=SUM(CASE WHEN C.[CODVOLO] IS NULL THEN 0 ELSE 1 END),
NCOLLI= SUM(CASE WHEN C.[CODVOLO] IS NULL THEN 0 ELSE NCOLLI END)
FROM BIGLIETTO B LEFT JOIN [CHECK-IN] C ON
(B.[DATA] = C.[DATA] AND B.[CODVOLO] = C.[CODVOLO] AND B.[POSTO] =
C.[POSTO])
GROUP BY
CONVERT(CHAR(11), B.DATA) + '__' + CONVERT(CHAR(3), B.CODVOLO),
CASE WHEN B.POSTO <=1 THEN 'PRIMA' ELSE 'SECONDA' END
Anche se non richiesto, per ottenere gli eventi primari e la dimension table dtVOLO
SELECT VOLO, CLASSE, COSTO=COSTO_SUM/COSTO_COUNT, NB, NBC, NCOLLI,
GUADAGNO_C = (COSTO_SUM/COSTO_COUNT)*NB, -- misura calcolata
GUADAGNO_D = COSTO_SUM *1) -- misura derivata aggregata con SUM
FROM FACT_TABLE
CREATE VIEW dtVOLO AS
SELECT VOLO = CONVERT(CHAR(11), DATA) + '__' + CONVERT(CHAR(3), CODVOLO),
DATA,COMPAGNIA, RITARDO
FROM VOLO
28
(0,N)
DI
(1,1)
ISCRI
TTO
(0,N)
(0,N)
(0,N)
GRUPPO
(1,1)
TIPO
RAPPRES
ENTANTE
(1,N)
ESAME
STUDENTE
DEL
(1,1)
(1,1)
(1,N)
CDS
ESAME
GRUPPO
(1,1)
DEL
(1,1)
DOCENTE
(1,N)
CON
(T,E)
GENERE
VOTO
NUMES
(0,N)
AFFERENZA
SEDE
(1,1)
FACOLTA
ESAME
DATA
(1,1)
TIPO_ESAME
(STUD/GRUP)
DI
(1,N)
(1,1)
APPELLO
FACOLTA(FACOLTA,REGIONE)
CDS(CDS,FACOLTA:FACOLTA,STUDENTE:STUDENTE)
DOCENTE(DOCENTE,FACOLTA:FACOLTA,CDL:CDL)
STUDENTE(STUDENTE, FACOLTA:FACOLTA)
APPELLO(APPELLO,DOCENTE:DOCENTE, GENERE)
ESAME(NUMES, APPELLO:APPELLO, DATA, TIPO_ESAME, VOTO)
AK: NUMES
ESAMEGRUPPO(NUMES:ESAME, GRUPPO:GRUPPO)
ESAMESTUDENTE(NUMES:ESAME, STUDENTE:STUDENTE) GRUPPO(GRUPPO,TIPO)
Viene richiesto:
A) Progettazione concettuale :Progettazione dello schema di fatto ESAME con
dimensioni
{ GRUPPO, STUDENTE, TIPOESAME,DATA, DOCENTE } dove
STUDENTE lo STUDENTE che ha sostenuto lesame
GRUPPO il GRUPPO che ha sostenuto lesame
misure
VOTO_MEDIO: il voto medio dellesame
NUM_APPELLI: il conteggio distinto degli appelli
B) Progettazione logica :Progettazione dello STARSCHEMA
C) Alimentazione : Scrivere in SQL lalimentazione della fact-table.
Esempio di istanze:
DBO: relazione ESAME
29
1.4.1
Soluzione
Progettazione Concettuale
Condivisione su STUDENTE:
STUDENTE che ha sostenuto lesame
STUDENTE rappresentante del CDS del DOCENTE
Condivisione su FACOLTA:
FACOLTA del DOCENTE
FACOLTA dello STUDENTE
FACOLTA dello STUDENTE rappresentante
Pattern primario =
{STUDENTE,DATA,GRUPPO}
DOCENTE
FACOLTA
CDS
STUDENTE
STUDENTE
T,E
ESAME
(C) VOTO_MEDIO (AVG)
T,E
NUM_APPELLI
DATA
NUM_APPELLI
TIPO
ESAME
GRUPPO
TIPO_ESAME
TIPO
GRUPPO
TIPO_ESAME
{ DOCENTE,STUDENTE,GRUPPO,TIPOESAME,DATA }
Misure normali
COUNT(DISTINCT ESAME.APPELLO), additiva con NA = {STUDENTE,DATA,GRUPPO}
Misure calcolate
VOTO_MEDIO = VOTO_TOT/ VOTO_COUNT
dove
VOTO_TOT = SUM(VOTO)
VOTO_COUNT = COUNT(*)
Fact Table FACT_TABLE(DATA,GRUPPO,STUDENTE,DOCENTE,TIPOESAME,
VOTO_TOT, VOTO_COUNT,NUM_APPELLI)
Progettazione Logica STARSCHEMA:
FACT_TABLE(DATA,GRUPPO:dtGRUPPO,STUDENTE:dtSTUDENTE,DOCENTE:dtDOCENTE
TIPOESAME,VOTO_TOT, VOTO_COUNT,NUM_APPELLI)
dtGRUPPO(GRUPPO,TIPO)
dtSTUDENTE(STUDENTE, FACOLTA, FACOLTA_REGIONE, FACOLTA_STATO)
dtDOCENTE(DOCENTE,FACOLTA, FACOLTA_REGIONE,
CDS,CDS_FACOLTA,CDS_FACOLTA_REGIONE,
CDS_STUDENTE,CDS_STUDENTE_FACOLTA,CDS_STUDENTE_FACOLTA_REGIONE )
30
Alimentazione
Laspetto caratteristico la presenza di dimensioni opzionali, il cui valore nullo viene opportunamente
codificato (si usa sempre 9999)
CREATE VIEW VIEW1 AS
SELECT
ESAME.*, ISNULL(ESAMESTUDENTE.STUDENTE,9999) AS STUDENTE,
ISNULL(ESAMEGRUPPO.GRUPPO,9999) AS GRUPPO
FROM
ESAME LEFT OUTER JOIN
ESAMEGRUPPO ON ESAME.NUMES = ESAMEGRUPPO.NUMES LEFT OUTER JOIN
ESAMESTUDENTE ON ESAME.NUMES = ESAMESTUDENTE.NUMES
CREATE VIEW FACT_TABLE AS
SELECT
GRUPPO, STUDENTE, TIPOESAME, DATA,DOCENTE,
COUNT(*) AS NUM_TOT,
SUM(VOTO) AS VOTO_TOT,
COUNT(VOTO) AS VOTO_COUNT,
COUNT(DISTINCT APPELLO.APPELLO) AS NUM_APPELLI
FROM VIEW1 NATURAL JOIN APPELLO
GROUP BY GRUPPO, STUDENTE, TIPOESAME, DATA,DOCENTE
Per semplicit si usa il NATURAL JOIN (in modo da evitare di scrivere la condizione di join).
E possibile usare il NATURAL JOIN anche per i join esterni, ovvero la scrittura della VIEW1 si pu
semplificare scrivendo:
CREATE VIEW VIEW1 AS
SELECT
ESAME.*, ISNULL(ESAMESTUDENTE.STUDENTE,9999) AS STUDENTE,
ISNULL(ESAMEGRUPPO.GRUPPO,9999) AS GRUPPO
FROM
ESAME
LEFT NATURAL JOIN ESAMEGRUPPO
LEFT NATURAL JOIN ESAMESTUDENTE
31
Viene
richiesto:
1) Reverse
Engineering:
Schema
E/R
equivalente
2) Progettazione
Concettuale:
Schema
di
Fatto
con
Dimensioni
=
{PRODOTTO,CASSA,COMMESSO,DATA}
e
Misure
i. NUMVENDITE
=
count(*)
ii. NUMCLIENTI
=
count(DISTINCT
NUMERO_SCONTRINO)
3) Progettazione
logica:
SNOWFLAKE
SCHEMA
4) Supponendo
che
lattributo
COMMESSO
assume
valore
NULL
per
le
vendite
senza
COMMESSO
e
un
valore
NON
NULLO
per
le
vendite
con
commesso,
considerare
lo
Schema
di
Fatto
con
Dimensioni
=
{PRODOTTO,CASSA,
DATA}
e
discutere
la
definizione
e
laggregabilit
della
misura
NUMVENDITE_CONCOMMESSO
:
conteggio
delle
vendite
con
COMMESSO
1.5.1
Soluzione
Schema
E/R:
VENDITA
(1,1)
CATEGORIA
IN
(1,1)
(1,N)
SCONTRINO
CON
(1,1)
COMM
DI
(1,N)
CASSA
GRUPPO
(1,N)
(1,N)
TIPO
HA
(1,1)
PRODOTTO
(1,N)
ALLA
CASSA
(1,N)
DATA
Schema
di
Fatto
VENDITA
CAT
GRUPPO
GRUPPO
CAT
TIPO
TIPO
PRODOTTO
PRODOTTO
VENDITA
NUMVENDITE
NUMCLIENTI
COMM
DATA
CASSA
VENDITA
NUMVENDIT
E
NUMCLIENTI
COMM
CASSA
DATA
32
Misure normali
NUMVENDITE= COUNT(*), additiva
NUMCLIENTI=COUNT(DISTINCT NUMERO_SCONTRINO), additiva
con NA = { PRODOTTO, COMM }
Per
valutare
quali
sono
i
pattern
per
i
quali
il
valore
aggregato
di
NUMCLIENTI
pu
essere
calcolato:
si
considera
lo
schema
equivalente
senza
FD
tra
le
dimensioni:
NA
=
{
PRODOTTO,
COMMESSO}.
SnowFlake
Schema
FACT_TABLE(PRODOTTO:dtPRODOTTO,DATA,COMMESSO,CASSA,NUMVENDITE,NUMCLIENTI)
dtPRODOTTO(PRODOTTO,TIPO:dtTIPO)
dtTIPO(TIPO,GRUPPO, CATEGORIA)
E
possibile
limitare
la
chiave
della
Fact
Table
al
solo
pattern
primario
{PRODOTTO,DATA,COMMESSO}
FACT_TABLE(PRODOTTO:dtPRODOTTO,DATA,COMMESSO,CASSA,NUMVENDITE,NUMCLIENTI)
E
inoltre
possibile
normalizzare
la
Fact
Table
al
solo
pattern
primario
{PRODOTTO,DATA,COMMESSO}:
FACT_TABLE(PRODOTTO:dtPRODOTTO, DATA,COMMESSO, NUMVENDITE,NUMCLIENTI)
dtPRODOTTO(PRODOTTO,TIPO:dtTIPO)
dtTIPO(TIPO,GRUPPO, CATEGORIA)
dtCASSA(PRODOTTO:dtPRODOTTO, DATA, CASSA)
33
CITTA
FILIALE
STATO
OPERAZIONE
(C) IMPORTO (AVG)
BANCA
BANCAASSEGNO
CONTOCORRENTE
CLIENTE
N_BANKOMAT
MESE
SESSO
COMMISSIONE
Soluzione
SNOWFLAKE SCHEMA
FACT_TABLE (MESE,FILIALE:DT_FILIALE,CC:DT_CC,BANCAASSEGNO:DT_BANCA,
NBANKOMAT, IMPORTO_SUM, IMPORTO_COUNT)
DT_BANCA(BANCA,STATO)
DT_CC(CC,CLIENTE:DT_CLIENTE)
DT_CLIENTE(CLIENTE,SESSO)
DT_FILIALE(FILIALE,CITTA:DT_CITTA, BANCA:DT_BANCA)
DT_CITTA(CITTA, REGIONE:DT_REGIONE)
DT_REGIONE(REGIONE, STATO)
DT_COMMISSIONE(BANCAASSEGNO:DT_BANCA,STATO,COMMISSIONE)
Arco multiplo tra CONTOCORRENTE e CLIENTE:
FACT_TABLE_PD(MESE,FILIALE:DT_FILIALE,CC:DT,BA:DT_BANCA,
CLIENTE:DT_CLIENTE,
NBANKOMAT_P, NBANKOMAT_NP,IMPORTO_SUM_P, IMPORTO_COUNT_P)
DT_CC(CC,CLIENTE:DT_CLIENTE)
Lo SNOWFLAKE SCHEMA uguale al precedente, si toglie solo DT_CC in quanto ora degenere.
34
CITTA
REGIONE
STATO
VIAGGIO
ANNO
NumITINERARI
PARTENZA
DISTRETTO
NumPERSONE
NumViaggi
DESTINAZIONE_STATO
AGENZIA
35
OPERATORE_CHIAMATO
SIM_CHIAMANTE
PREFISSO
TELEFONATA
DATA
NumSIM_CHIAMANTI
TARIFFA
NumSIM_CHIAMATE
UTENTE
DURATA_MEDIA
UTENTE_CHIAMATO
CITTA
Fatto TELEFONATA(NP,DATA,DA_CHIAMANTE:SIM, A_CHIAMATO:SIM,DURATA)
Dimensioni =
{DATA, SIM_CHIAMANTE, OPERATORE_CHIAMATO, UTENTE_CHIAMATO }
Granularit: Temporale
Dipendenze funzionale tra le dimensioni: Nessuna
Misure normali
NumSIM_CHIAMATE =COUNT(DISTINCT A_CHIAMATA), additiva
con NA = {DATA, SIM_CHIAMANTE }
in quanto A_CHIAMATA { OPERATORE_CHIAMATO, UTENTE_CHIAMATO }
Misure calcolate
DURATA_MEDIA - misura calcolata DURATA_TOT/ DURATA_COUNT con
DURATA_TOT = SUM(DURATA)
DURATA_COUNT = COUNT(DURATA)
Misure derivate
NumSIM_CHIAMANTI
=
COUNT(DISTINCT
DA_CHIAMANTE)
misura
derivata
dal
valore
di
una
dimensione;
per
gli
eventi
primari
vale
1;
per
gli
eventi
secondari
si
usa
COUNT(DISTINCT
DA_CHIAMANTE).
Star
Schema
La dimensione OPERATORE_CHIAMATO degenere quindi non richiede dimension table.
La misura NumSIM_CHIAMANTI derivata quindi non nella FACT_TABLE.
FACT_TABLE(DATA, OPERATORE_CHIAMATO,
SIM_CHIAMANTE:DT_SIM_CHIAMANTE,
UTENTE_CHIAMATO: DT_UTENTE_CHIAMATO,
DURATA_COUNT, DURATA_TOT, NumSIM_CHIAMATE)
DT_SIM_CHIAMANTE(SIM,TARIFFA,PREFISSO,OPERATORE,UTENTE,CITTA)
DT_UTENTE_CHIAMATO(UTENTE,CITTA)
36
GENERE
ISTITUZIONE
ANNO
CONTRATTO
CONTRAENTE
DURATA
IMPORTO
NUMERO
TIPO
STATO
CONVENZIONE
PERSONA
CITTA
TITOLO
COMMITTENTE_CITTA
37
Misure normali
DURATA, additiva
IMPORTO, additiva
Essendo lo schema transazionale la misura NUMERO pu essere considerata come misura vuota, da
aggregare tramite count(*) e quindi non verr riportata nella FACT_TABLE.
Star
Schema
FACT_TABLE(CONVENZIONE:DTCONVENZIONE,CONTRAENTE:DTCONTRAENTE,
COMMITTENTE_CITTA:DTCOMMITTENTE_CITTA, ANNO, TIPO, DURATA,IMPORTO)
DTCOMMITTENTE_CITTA(CITTA, STATO)
DTCONVENZIONE(CONVENZIONE, GENERE,ISTITUZIONE,
DIRETTORE, DIRETTORE_TITOLO,DIRETTORE_CITTA, DIRETTORE_STATO,
SEDE_CITTA, SEDE_STATO)
DTCONTRAENTE(PERSONA, TITOLO, CITTA, STATO,)
38