Basi Di Dati, 09/12/2003 Una concessionaria di auto nuove ed usate

Transcript

Basi Di Dati, 09/12/2003 Una concessionaria di auto nuove ed usate
Basi Di Dati, 09/12/2003
Una concessionaria di auto nuove ed usate vuole automatizzare alcune delle sue attività.
L’attività che la concessionaria vuole automatizzare riguarda la gestione delle auto nuove,
usate, di cortesia ed in riparazione presso l’officina. La concessionaria tratta diversi modelli di
auto appartenenti anche a case automobilistiche differenti e gestisce gli interventi dell’officina
solo se il cliente effettua una prenotazione dell’intervento su un auto. In tale prenotazione il
cliente può richiedere, per un preciso periodo, un auto di cortesia tra quelle disponibili alla
concessionaria nel periodo indicato. E’necessario tener traccia: di tutti i contratti di vendita di
auto nuove ed usate (data, numero contratto, prezzo, termini di pagamento, ecc), delle
prenotazioni di intervento richieste all’officina (auto, cliente, guasto, giorno, ora), delle auto di
cortesia assegnate ai clienti che ne hanno fatto espressa richiesta ed infine degli interventi
effettuati dall’officina su qualunque auto gestita dalla concessionaria (interventi su auto nuove,
usate, in riparazione e di cortesia).
Per la progettazione del database i responsabili della concessionaria si rivolgono ad una
software house specializzata.
1. Si definisca un diagramma ER che modelli la realtà commentandolo ed indicando le
ipotesi fatte.
2. Si derivi dal diagramma ER il modello relazionale corrispondente.
3. Si implementino in linguaggio SQL o si esprimano mediante algebra relazionale le
seguenti interrogazioni:
a. Elenco degli interventi effettuati nel 2003 su auto FIAT in riparazione e di cortesia.
b. Totale fatturato (nuovo ed usato) per casa automobilistica nel primo trimestre
dell’anno 2003.
c. Elenco della spesa media sostenuta dai clienti per le auto nuove ed usate che hanno
richiesto interventi dall’officina negli ultimi 10 anni dalla data di acquisto.
MODELLO ER
Le entità del diagramma er sono:
Cliente (CodiceFiscale, Nome, Cognome, Indirizzo, DatadiNascita);
TipoIntervento (CodiceIntervento, CostoListino, Guasto, Descrizione);
Auto (NumTelaio, CodiceImmatricolazione, AnnoImmatricolazione, CasaAutomobilistica,
Targa).
L’entità auto si può specializzare in “Auto di Cortesia”, in “Auto in Riparazione” e “Auto in
vendita”, quest’ultima caratterizzata dal flag S/N che sta ad indicare se l’auto in vendita è
nuova (S) o usata (N).
Le auto di cortesia vengono cedute in prestito ai clienti che ne fanno richiesta in seguito ad un
intervento: abbiamo ipotizzato che un cliente possa richiedere in prestito più di un’auto di
cortesia. Il cliente acquista, stipulando un contratto di vendita, un’auto in vendita.
L’autofficina effettua interventi su qualunque auto della concessionaria: sia su auto nuove,
usate, in riparazione e di cortesia.
MODELLO RELAZIONALE
Dal diagramma ER ricaviamo ora il modello relazionale sfruttando le regole dell’algoritmo di
mapping. Per tradurre la specializzazione precedentemente definita abbiamo scelto di creare
oltre alla tabella AUTO anche le tabelle AUTODICORTESIA e AUTOINVENDITA che usano come
chiave primaria la stessa chiave primaria dell’entità padre AUTO.
Otteniamo le seguenti tabelle:
CLIENTE
CODICE FISCALE
NOME
TIPOINTERVENTO
CODICEINTERVENTO
AUTO
NUMTELAIO
COGNOME
COSTOLISTINO
GUASTO
COD_IMMATRICOLAZIONE
DATAINT
DATADINASCITA
ORAINT
ANNO_IMMATR
INDIRIZZO
CFCLIENTE
CASA
DESCRIZIONE
MODELLO
TARGA
AUTO DI CORTESIA
NUMTELAIO
AUTO IN VENDITA
NUMTELAIO
S/N
AUTO IN RIPARAZIONE
NUMTELAIO
PRENOTA
CALENDARIO
ACQUISTA
NUMCONTRATTO
ESEGUITOSU
CODINTERVENTO
CFCLIENTE_RICHIEDENTE
CFACQUIRENTE
NUMTELAIO_AUTOINVEN
NUMTELAIOAUTO
COSTOEFFETTIVO
NUMTELAIO_AUTOCORTESIA
PREZZO
DATA
TERMINIPAGAMENTO
GUASTOEFFETTIVO
DATA
ORA
Si implementino in linguaggio SQL o si esprimano mediante algebra relazionale le seguenti
interrogazioni:
1. Elenco degli interventi effettuati nel 2003 su auto FIAT in riparazione e di cortesia
Scegliamo inizialmente di effettuare i JOIN tra la tabella AUTO e AUTODICORTESIA e AUTO e
AUTOINRIPARAZIONE, unendo i risultati. Successivamente eseguiamo il JOIN con la tabella
ESEGUITOSU. L’interrogazione restituisce tutti i record in cui esiste una corrispondenza tra le
tabelle, ovvero l’elenco completo di tutte le auto (sia di cortesia che in riparazione) che hanno
subito un intervento. Raffiniamo ulteriormente l’interrogazione, selezionando tra tutte le righe
quelle che soddisfano la condizione casautomobilistica=’fiat’ e data=’??/??/2003’, con il
carattere ? che può rappresentare qualsiasi singolo carattere. Generiamo infine una vista,
scegliendo tra quelle presenti le colonne opportune: nel nostro caso abbiamo scelto
ESEGUITOSU.GUASTOEFFETTIVO e AUTO.MODELLO. Il risultato conclusivo è:
B∏<ESEGUITOSU.GUASTOEFFETTIVO, AUTO.MODELLO>(ơ<casa=’fiat’ and
data=’??/??/2003’>(ESEGUITOSU
A ((AUTO
(AUTO
<ESEGUITOSU.NUMTELAIOAUTO=A.NUMTELAIO>)
<AUTO.NUMTELAIO=AUTODICORTESIA.NUMTELAIO>AUTODICORTESIA)
U
<AUTO.NUMTELAIO=AUTOINRIPARAZIONE.NUMTELAIO> AUTOINRIPARAZIONE))
SQL
SELECT
FROM
WHERE
ESEGUITOSU.GUASTOEFFETTIVO, AUTO.MODELLO
AUTO, AUTOINRIPARAZIONE, ESEGUITOSU
AUTO.CASA=’fiat’ AND ESEGUITOSU.DATA=#__/__/2003#
AND AUTO.NUMTELAIO=AUTOINRIPARAZIONE.NUMTELAIO
AND AUTOINRIPARAZIONE.NUMTELAIO=ESEGUITOSU.NUMTELAIOAUTO
UNION
SELECT
FROM
WHERE
ESEGUITOSU.GUASTOEFFETTIVO, AUTO. MODELLO
AUTO, AUTODICORTESIA, ESEGUITOSU
AUTO.CASA=’fiat’ AND ESEGUITOSU.DATA=#__/__/2003#
AND AUTO.NUMTELAIO=AUTODICORTESIA.NUMTELAIO
AND AUTODICORTESIA.NUMTELAIO=ESEGUITOSU.NUMTELAIOAUTO
2. Totale fatturato (nuovo ed usato) per casa automobilistica nel primo trimestre dell’anno
2003.
Effettuando il join tra le tabelle AUTO e AUTOINVENDITA, imponendo come condizione di join
AUTOINVENDITA.NUMTELAIO=AUTO.NUMTELAIO otteniamo tutti i record in cui esiste una
corrispondenza tra le due tabelle, ovvero l’elenco di tutte le auto in vendita, correlato dei
campi CASA, TARGA, MODELLO, ANNO_IMMATR, COD_IMMATRICOLAZIONE.
Effettuiamo un secondo join con la tabella ACQUISTA: otteniamo così l’elenco di tutte le auto
oggetto di un contratto di vendita. La condizione imposta sarà:
AUTOINVENDITA.NUMTELAIO=ACQUISTA.NUMTELAIO_AUTOINVEN.
Raffiniamo ulteriormente la query selezionando quelle vendute tra il 01/01/2003 e il
31/03/2003, estremi inclusi. Infine operiamo con il raggruppamento, scegliendo come attributo
di raggruppamento CASA, calcolando per ciascuna di essa il fatturato totale, facendo la somma
dei relativi prezzi.
<AUTO.CASA>F<sum ACQUISTA.PREZZO>(ơ<01/01/2003≤ACQUISTA.DATA≤31/03/2003>
< ACQUISTA.NUMTELAIO_AUTOINVEN=AUTOINVENDITA.NUMTELAIO>
(ACQUISTA
(AUTOINVENDITA
<AUTOINVENDITA.NUMTELAIO=AUTO.NUMTELAIO>AUTO)))
SQL
SELECT
FROM
WHERE
SUM(ACQUISTA.PREZZO)
ACQUISTA, AUTOINVENDITA, AUTO
ACQUISTA.DATA BETWEEN #01/01/2003# AND #31/03/2003#
AND ACQUISTA.NUMTELAIO_AUTOINVEN=AUTOINVENDITA.NUMTELAIO
AND AUTOINVENDITA.NUMTELAIO=AUTO.NUMTELAIO
GROUP BY AUTO.CASA
3. Elenco della spesa media sostenuta dai clienti per le auto nuove ed usate che hanno
richiesto interventi dall’officina negli ultimi 10 anni dalla data di acquisto.
Generiamo la nostra interrogazione partendo dal join tra le tabelle CLIENTE e
TIPOINTERVENTO, imponendo come condizione di join
CLIENTE.CODICEFISCALE=TIPOINTERVENTO.CFCLIENTE. Otteniamo un elenco di tuple con
tutti i clienti che hanno effettuato la prenotazione di un intervento sulla propria (o sulle
proprie) auto. Proseguiamo con un secondo join tra le tabelle TIPOINTERVENTO e
ESEGUITOSU, imponendo come condizione
TIPOINTERVENTO.CODICEINTERVENTO=ESEGUITOSU.CODINTERVENTO.
Effettuiamo infine un join con la tabella ACQUISTA (condizione di join:
ACQUISTA.CFACQUIRENTE=CLIENTE.CODICEFISCALE) in modo tale da ricavare anche i
dettagli riguardo la data di stipula del contratto. Selezioniamo ora tutti gli interventi che sono
stati effettuati a 10 anni dalla data di acquisto imponendo la condizione:
ACQUISTA.DATA≤TIPOINTERVENTO.DATAINT≤ACQUISTA.DATA + 00/00/0010. Infine
calcoliamo la media con la funzione raggruppamento, scegliendo come attributo di
raggruppamento il codice fiscale di ciascun cliente. Otteniamo così l’interrogazione completa:
<CLIENTE.CODICEFISCALE>F<AVG ESEGUITOSU.COSTOEFFETTIVO> (ơ< ACQUISTA.DATA
≤TIPOINTERVENTO.DATAINT≤ACQUISTA.DATA + 00/00/0010>(ESEGUITOSU
< ESEGUITOSU.CODINTERVENTO = TIPOINTERVENTO.CODICEINTERVENTO >(
TIPOINTERVENTO
<TIPOINTERVENTO.CFCLIENTE=CLIENTE.CODICEFISCALE >
(ACQUISTA
< ACQUISTA.CFACQUIRENTE=CLIENTE.CODICEFISCALE >CLIENTE))))
SQL
SELECT
FROM
WHERE
AVG(ESEGUITOSU.COSTOEFFETTIVO), DateAdd (“yyyy”, 10,
ACQUISTA.DATA) AS DATA2
ACQUISTA, CLIENTE, TIPOINTERVENTO, ESEGUITOSU
TIPOINTERVENTO.DATAINT BETWEEN ACQUISTA.DATA AND DATA2
AND ACQUISTA.CFACQUIRENTE=CLIENTE.CODICEFISCALE
AND CLIENTE.CODICEFISCALE=TIPOINTERVENTO.CFCLIENTE
AND TIPOINTERVENTO.CODICEINTERVENTO= ESEGUITOSU.CODINTERVENTO
GROUP BY CLIENTE.CODICEFISCALE
Abbiamo utilizzato nell’ultima query la funzione DateAdd:
DateAdd (tipocalcolo, valore, data)
Fornisce una data che è il risultato tra data e valore il cui significato è indicato da tipocalcolo.
Es. DateAdd(“m”, 7, data_nascita)
Addiziona 7 mesi alla data di nascita, ottenendo la data corrispondente.
Errori di modellazione
L’errore di modellazione più ricorrente è quello di aver strutturato il diagramma ER in modo
tale da non individuare quali auto da cortesia siano disponibili per la cessione temporanea a un
cliente che ne effettua richiesta o quali auto siano in riparazione.
Quella di non distinguere una gerarchia di auto (di cortesia, in vendita e in riparazione) può
ulteriormente complicare la realizzazione delle successive interrogazioni. In alcuni casi è stata
considerata un’unica entità auto senza effettuare una ulteriore specializzazione e senza
utilizzare un flag o un altro metodo alternativo per distinguere un’auto nuova da una usata. In
alcuni diagrammi sono assenti alcune relazioni di notevole rilievo: CLIENTE – INTERVENTO –
AUTODICORTESIA, AUTOINRIPARAZIONE. Usare un modello troppo esemplificato può portare
a non effettuare alcune interrogazioni di rilievo, come ad esempio quella di verificare quali auto
di cortesia siano state assegnate. Sempre a questo scopo nella relazione CLIENTE – richiede –
AUTODICORTESIA è fondamentale inserire come attributo della relazione il “calendario”, che
semplifica l’esecuzione di alcune query sulle date.
Errori di notazione: esempi di cardinalità errate nel diagramma ER
Errori di mapping ER-Relazionale
Innanzitutto occorre ricordare la necessità di avere una congruenza tra modello ER e modello
relazionale: è obbligatorio non solo utilizzare la stessa notazione, ma rispettare
nell’applicazione dell’algoritmo di mapping le cardinalità espresse nel diagramma ER.
Tra quelli analizzati emergono soprattutto errori di traduzione:
- CLIENTE –(0,N) effettua –(1,1) PRENOTAZIONE: nella tabella CLIENTE è assente la chiave
esterna “codiceprenotazione”
- PRENOTAZIONE –(1,1) richiede –(1,1) AUTODICORTESIA: nessuna chiave è stata inglobata né
nella tabella PRENOTAZIONE né in AUTODICORTESIA.
- CLIENTE –(1,N) acquista –(1,1) AUTO: è stata tradotta erroneamente come una relazione M:N.
- PRENOTAZIONE –(0,1) include –(0,N) AUTODICORTESIA: manca la chiave esterna
IDPRENOTAZIONE nella tabella AUTODICORTESIA.
Errori SQL o algebra relazionale
Tra quelli riscontrati emergono numerosi errori di notazione, ne riportiamo alcuni effettuando
alcune considerazioni.
- Nell’operazione di JOIN esprimere sempre e correttamente la relativa condizione di JOIN;
- Utilizzare correttamente la funzione di aggregazione: <attributo di raggruppamento>F<lista
delle funzioni>. Evitare errori del tipo <modello, prezzo> F <SUM prezzo>;
- Sarebbe utile evitare ambiguità nelle interrogazioni usando la notazione TABELLA.CAMPO e
non CAMPO.TABELLA;
- Nelle query sql utilizzare correttamente i caratteri speciali:
AND DATASTIPULA=#__/__/2003# non AND DATASTIPULA=’ / /2003’. Inoltre quando date e
orari fanno parte di una condizione di query vanno delimitati dal carattere cancelletto #.
Ricordiamo i caratteri speciali da utilizzare nelle query SQL:
% sostituisce un arbitrario numero di lettere
_ sostituisce una arbitraria lettera
- Errore di notazione: per selezionare tutte le colonne di una tabella si usa SELECT * FROM
TABELLA non SELECT *.TABELLA;
- Quando si effettuano operazioni di raggruppamento inserire il GROUP BY TABELLA.CAMPO.