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.