GESTIONE ESAMI di STATO Si vogliono gestire, con una base di dati, le informazioni relative ai risultati delle prove, riguardanti l'esame di stato, sostenute da un classe di alunni. Gli elementi caratterizzanti il problema sono : gli alunni e le prove (prima prova scritta, seconda prova scritta, terza prova scritta e orale). Per ottenere i risultati definitivi occorre tener presente anche il credito scolastico per ciascun alunno. Considerato il problema proposto si realizzi: uno schema concettuale della base di dati; uno schema logico della base di dati; la definizione delle relazioni della base di dati in linguaggio SQL. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 1
Schema concettuale della base di dati Tipi di entità Le entità che possono essere individuate per risolvere il problema sono : Prova Alunno contiene l elenco delle prove d esame (prima, seconda, terza, orale); contiene l elenco anagrafico degli alunni che sostengono l esame; Attributi Tipo di entità Prova Alunno Sistema informativo Gestione Esami di Stato Attributi idprova, descrizione; idalunno, cognome, nome, data di nascita, crediti; Relazioni fra le entità Le associazioni tra i tipi di entità nel modello dei dati sono individuate nel seguente Modello Entità/Relazioni (E/R) : ALUNNO Esito PROVA Voto Tra l entità Alunno e l entità Prova esiste un associazione molti-a-molti in quanto un alunno deve sostenere tutte le prove d esame e ciascuna prova d esame deve essere sostenuta da tutti gli alunni. Nel modello E/R, inoltre, sono stati indicati, oltre ai nomi delle entità, l opzionalità od obbligatorietà delle associazioni (indicate rispettivamente con linea tratteggiata o continua). Il modello viene verificato utilizzando le regole di lettura : ogni alunno deve sostenere tutte le prove d esame e ogni prova deve essere sostenuta da tutti gli alunni. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 2
Schema logico della base di dati Nello schema E/R precedente si può osservare che esiste una relazione molti-a-molti (N:N) tra i tipi di entità Alunno e Prova. Applicando il processo di normalizzazione (definito dalle forme normali) si deve inserire una entità ausiliaria (Esito) che trasforma la relazione molti-a-molti in due relazioni : uno-a-molti (1:N) tra Alunno e Esito, e molti-a-uno (N:1) tra Esito e Prova. Applicando le regole di corrispondenza tra il modello E/R ed il modello Relazionale si passa dal precedente schema concettuale al modello logico che viene descritto sia nella forma testuale che in quella grafica. Rappresentazione testuale dello schema logico : Nella rappresentazione testuale si elencano le tabelle (indicando per ciascuna i campi) che rappresentano le entità dello schema concettuale e le tabelle che rappresentano le eventuali relazioni molti-a-molti, introducendo, inoltre, le chiave esterne per rappresentare le associazioni (le chiavi primarie sono sottolineate, le chiavi esterne sono in corsivo). Si elencano di seguito le tabelle che rappresentano le entità dello schema concettuale : tbprove (idprova, prova) tbalunni (idalunno, cognome, nome, datanascita, crediti) tbesiti (ksalunno, ksprova, voto) Per realizzare l associazione molti-a-molti fra l entità Alunno e l entità Prova si introduce una terza entità Esito, che, oltre ad attributi propri dell associazione (voto) ha, come attributi, la chiave esterna ksalunno associata alla chiave primaria idalunno dell entità Alunno e la chiave esterna ksprova associata alla chiave primaria idprova dell entità Prova. Rappresentazione grafica dello schema logico : La rappresentazione grafica dello schema logico relativo al sistema informativo per la gestione degli Esami di Stato è il seguente : Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 3
Definizione delle Tabelle Nel definire le tabelle e la struttura delle stesse, è consigliabile elencarle partendo dalle tabelle che non presentano chiavi esterne. In successione si definiscono le tabelle le cui chiavi primarie sono utilizzate da altre tabelle come chiavi esterne. Nel prospetto seguente, per es., si definiscono prima le tabelle tbprove e tbalunni e successivamente la tabella tbesiti in quanto quest ultima ha, fra gli attributi, un campo definito come chiave esterna alla tabella tbprove ed un campo definito come chiave esterna alla tabella tbalunni (l insieme di questi due campi formano la chiave primaria). Tabella Nome campo Chiave Tipo dati Dim. Dec. Null Descrizione tbprove idprova Primaria Numerico 4 Autoincremento prova Testo 10 Vincolo : valori unici tbalunni idalunno Primaria Numerico 4 Autoincremento cognome Testo 20 nome Testo 20 datanascita Data/ora 10 crediti Numerico 2 totale credito scolastico tbesiti ksalunno Primaria Numerico 4 Integrità referenziale con idalunno della tabella tbalunni ksprova Primaria Numerico 4 Integrità referenziale con idprova della tabella tbprove voto Numerico 2 Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 4
Definizione delle relazioni della base di dati in SQL Lo schema logico relazionale precedente (tabelle, relazione ed applicazione dei vincoli di integrità dei dati e referenziale) può essere creato con le seguenti istruzioni SQL (proposte in versione per ACCESS e MYSQL. ACCESS CREATE TABLE tbprove ( idprova Counter PRIMARY KEY, prova Char(10) NOT NULL UNIQUE); CREATE TABLE tbalunni ( idalunno Counter PRIMARY KEY, cognome Char(20) NOT NULL nome Char(20) NOT NULL datanascita Datetime, crediti short NOT NULL); CREATE TABLE tbesiti ( ksalunno Long NOT NULL, ksprova Long NOT NULL, voto short NOT NULL, PRIMARY KEY (ksalunno, ksprova), FOREIGN KEY(ksalunno) REFERENCES tbalunni(idalunno), FOREIGN KEY(ksprova) REFERENCES tbprove(idprova)); MySQL CREATE TABLE tbprove ( idprova int(4) AUTO_INCREMENT PRIMARY KEY, prova varchar(10) NOT NULL UNIQUE) TYPE=MyISAM; CREATE TABLE tbalunni ( idalunno int(4) AUTO_INCREMENT PRIMARY KEY, cognome varchar(20) NOT NULL, nome varchar(20) NOT NULL, datanascita date NOT NULL, crediti tinyint NOT NULL) TYPE=MyISAM; CREATE TABLE tbesiti ( ksalunno int(4) NOT NULL, ksprova int(4) NOT NULL, voto tinyint NOT NULL, PRIMARY KEY (ksalunno,ksprova)) TYPE=MyISAM; Nota : le istruzioni proposte per MySQL sono relative all uso di tabelle tipo MyISAM che non supportano l integrità referenziale definita con FOREIGN KEY. Il tipo di tabella InnoDB, invece, supporta la FOREIGN KEY similmente ad ACCESS. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 5
OSSERVAZIONI SULLE QUERY PROPOSTE Query n. 4) Risultato dell esame con l indicazione, per ogni alunno (attenzione alle omonimie), del punteggio complessivo delle prove sostenute, del credito scolastico e della relativa somma : SELECT CONCAT(cognome,' ', nome) AS Alunno, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita, SUM(voto) AS Punteggio_Prove, crediti, SUM(voto) + crediti AS Punteggio_Esame FROM tbalunni, tbesiti WHERE idalunno=ksalunno GROUP BY idalunno,cognome,nome,datanascita,crediti ORDER BY cognome,nome,datanascita; Alunno data_nascita Punteggio_Prove crediti Punteggio_Esame BIANCHI ANGELO 12-08-1989 49 18 67 DE ANGELIS CESARE 10-12-1988 47 10 57 DE PAOLIS ANDREA 17-05-1990 34 12 46 FORNACI ANTONIO 13-07-1988 80 9 89 FRANCO CESARE 11-09-1987 53 11 64 ROSSI MARIO 15-09-1989 50 10 60 ROSSI MARIO 15-09-1989 42 9 51 SOTTOMANO MARCO 08-10-1989 60 10 70 VERDI VITTORIO 13-02-1989 57 13 70 VERDI VITTORIO 15-11-1990 70 16 86 Nota : nella target list il nome di una colonna attribuito mediante la clausola AS non può essere utilizzato anche come parametro in ulteriori calcoli. Il Punteggio_Esame, per esempio, non può, come in Access, essere ottenuto nel seguente modo : Punteggio_Prove + crediti AS Punteggio_Esame Gestione delle omonimie : nella GROUP BY, oltre ai campi cognome, nome, datanascita e crediti che sono inseriti perché devono essere visualizzati, è stato inserito anche il campo idalunno. L inserimento di questo campo (che rappresenta la chiave primaria) si rende necessario per poter essere sicuri di distinguere un alunno da un altro e, quindi, di non raggruppare dati che appartengono ad alunni diversi ma con lo stesso nome e cognome. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 6
Se nella GROUP BY indichiamo solo il cognome e nome : GROUP BY cognome, nome i record risultanti verrebbero raggruppati solo per cognome e nome e quindi si avrebbe un unico record in casi di omonimia. Nell esempio proposto esistono due alunni (ROSSI MARIO) che oltre allo stesso cognome e nome hanno anche la stessa data di nascita (situazione poco probabile ma da considerare) e quindi anche se si inserisce la data di nascita nella GROUP BY GROUP BY cognome, nome, datanascita non si riescono a distinguere. In particolare, considerando i dati dell esempio proposto, si otterrebbe un risultato corretto anche non inserendo il campo idalunno ma solo perché, casualmente, i due alunni hanno un credito scolastico diverso e quindi complessivamente i campi cognome, nome, datanascita e crediti fanno riferimento ai due alunni separatamente. Se, invece, anche il credito scolastico fosse uguale con una GROUP BY così realizzata : GROUP BY cognome, nome, datanascita, crediti si avrebbe il seguente risultato (con un solo alunno ROSSI MARIO ma con la somma delle prove di entrambi) : Alunno data_nascita Punteggio_Prove crediti Punteggio_Esame BIANCHI ANGELO 12-08-1989 49 18 67 DE ANGELIS CESARE 10-12-1988 47 10 57 DE PAOLIS ANDREA 17-05-1990 34 12 46 FORNACI ANTONIO 13-07-1988 80 9 89 FRANCO CESARE 11-09-1987 53 11 64 ROSSI MARIO 15-09-1989 92 10 102 SOTTOMANO MARCO 08-10-1989 60 10 70 VERDI VITTORIO 13-02-1989 57 13 70 VERDI VITTORIO 15-11-1990 70 16 86 In definitiva, quando situazioni come nell esempio lo richiedono, solo la chiave primaria consente di distinguere correttamente i record e pertanto va inserita nella clausola GROUP BY. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 7
Query n. 7) Elenco degli alunni con la relativa media ottenuta in tutte le prove d esame : SELECT idalunno AS Codice, CONCAT(cognome,' ', nome) AS Alunno, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita, AVG(voto) AS Media_prove FROM tbalunni,tbesiti WHERE idalunno=ksalunno GROUP BY idalunno, cognome, nome ORDER BY cognome, nome; Codice Alunno data_nascita Media_prove 1 BIANCHI ANGELO 12-08-1989 16.3333 9 DE ANGELIS CESARE 10-12-1988 11.7500 4 DE PAOLIS ANDREA 17-05-1990 8.5000 5 FORNACI ANTONIO 13-07-1988 20.0000 7 FRANCO CESARE 11-09-1987 17.6667 2 ROSSI MARIO 15-09-1989 12.5000 8 ROSSI MARIO 15-09-1989 10.5000 6 SOTTOMANO MARCO 08-10-1989 15.0000 10 VERDI VITTORIO 13-02-1989 14.2500 3 VERDI VITTORIO 15-11-1990 17.5000 Nota : la clausola ORDER BY si rende necessaria in quanto nella GROUP BY sono stati inseriti, nell ordine, i campi idalunno, cognome e nome e quindi il primo campo preso in considerazione è idalunno e successivamente gli altri due. Se, quindi, non viene aggiunta la clausola ORDER BY cognome, nome si avrebbe il seguente risultato, un elenco ordinato rispetto al campo idalunno : Codice Alunno data_nascita Media_prove 1 BIANCHI ANGELO 12-08-1989 16.3333 2 ROSSI MARIO 15-09-1989 12.5000 3 VERDI VITTORIO 15-11-1990 17.5000 4 DE PAOLIS ANDREA 17-05-1990 8.5000 5 FORNACI ANTONIO 13-07-1988 20.0000 6 SOTTOMANO MARCO 08-10-1989 15.0000 7 FRANCO CESARE 11-09-1987 17.6667 8 ROSSI MARIO 15-09-1989 10.5000 9 DE ANGELIS CESARE 10-12-1988 11.7500 10 VERDI VITTORIO 13-02-1989 14.2500 Una soluzione, senza la clausola ORDER BY, sicuramente migliore è la seguente: GROUP BY cognome, nome, idalunno Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 8
Query n. 9) Elenco con la descrizione delle prove e la corrispondente media dei voti di tutti gli alunni per ciascuna prova : SELECT prova, AVG(voto) AS Media_voti FROM tbesiti,tbprove WHERE idprova=ksprova GROUP BY idprova,prova; prova Media_voti PRIMA 9.6250 SECONDA 11.2000 TERZA 12.1000 ORALE 23.2000 Nota : in questo caso potrebbe essere superfluo inserire nella GROUP BY il campo idprova perché, comunque, utilizzando solo il campo prova si avrebbe un risultato corretto in quanto tale campo è sottoposto al vincolo di unicità. Il risultato ottenuto, come mostrato successivamente, è una tabella ordinata in senso crescente rispetto alla descrizione della prova e non rispetto al codice prova: SELECT prova, AVG(voto) AS Media_voti FROM tbesiti,tbprove WHERE idprova=ksprova GROUP BY prova; prova Media_voti ORALE 23.2000 PRIMA 9.6250 SECONDA 11.2000 TERZA 12.1000 Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 9
Query n. 11) Elenco degli alunni che hanno preso 15 in una qualsiasi prova : SELECT idalunno AS Codice, CONCAT(cognome,' ', nome) AS Alunno, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita FROM tbalunni WHERE idalunno IN (SELECT ksalunno FROM tbesiti WHERE Voto =15 ) ORDER BY cognome, nome Codice Alunno data_nascita 1 BIANCHI ANGELO 12-08-1989 5 FORNACI ANTONIO 13-07-1988 8 ROSSI MARIO 15-09-1989 6 SOTTOMANO MARCO 08-10-1989 3 VERDI VITTORIO 15-11-1990 La subquery : SELECT ksalunno FROM tbesiti WHERE Voto =15 preleva dalla tabella tbesiti tutti i record in cui il voto è uguale a 15 e quindi il codice alunno corrispondente (ksalunno) può ripetersi più volte in quanto uno stesso alunno può prendere il voto 15 in più prove : ksalunno 5 3 5 6 1 3 5 8 La query principale, utilizzando il predicato IN, consente di confrontare ciascun codice alunno (idalunno) della tabella tbalunni con quelli presenti nella tabella ottenuta dalla subquery e quindi di ottenere un elenco senza ripetizioni. Lo stesso risultato, comunque, si può anche ottenere con una query diversa ma sicuramente più semplice : SELECT DISTINCT idalunno AS Codice,cognome,nome, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita FROM tbalunni,tbesiti WHERE idalunno = ksalunno AND voto=15 ORDER BY cognome,nome; Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 10
Query n. 13) Calcolare la prova con la media più alta : SELECT prova, AVG(voto) AS Media_max FROM tbesiti, tbprove WHERE idprova=ksprova GROUP BY prova HAVING AVG(voto) = (SELECT MAX(media) FROM (SELECT AVG(voto) AS media FROM tbesiti GROUP BY ksprova) AS Calcolo_media); prova Media_max ORALE 23.2000 La subquery : SELECT AVG(voto) AS media FROM tbesiti GROUP BY ksprova calcola la media per ciascuna prova : media 9.6250 11.2000 12.1000 23.2000 La subquery SELECT MAX(media) FROM (SELECT AVG(voto) AS media FROM tbesiti GROUP BY ksprova) AS Calcolo_media; preleva dalla tabella, ottenuta con la subquery precedente, il valore max : MAX(media) 23.2000 Nota : nella precedente subquery è stato specificato l alias Calcolo_media altrimenti viene segnalato il seguente errore : Every derived table must have its own alias nella esecuzione della query! Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 11
Query n. 19) Elenco degli alunni con i voti attribuiti nelle singole prove ed il totale delle prove : SELECT idalunno AS Codice,cognome,nome, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita, (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 1) AS 'PRIMA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 2) AS 'SECONDA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 3) AS 'TERZA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 4) AS 'ORALE', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 1) + (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 2) + (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 3) + (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 3) AS Punteggio FROM tbalunni ORDER BY cognome, nome,datanascita Codice Alunno data_nascita PRIMA SECONDA TERZA ORALE Punteggio 1 BIANCHI ANGELO 12-08-1989 12 12 15 22 61 9 DE ANGELIS CESARE 10-12-1988 7 8 10 22 47 4 DE PAOLIS ANDREA 17-05-1990 8 8 8 10 34 5 FORNACI ANTONIO 13-07-1988 15 15 15 35 80 7 FRANCO CESARE 11-09-1987 10 11 14 28 63 2 ROSSI MARIO 15-09-1989 8 10 12 20 50 8 ROSSI MARIO 15-09-1989 9 8 10 15 42 6 SOTTOMANO MARCO 08-10-1989 10 15 11 24 60 10 VERDI VITTORIO 13-02-1989 10 10 11 26 57 3 VERDI VITTORIO 15-11-1990 10 15 15 30 70 Nota : la query SELECT idalunno AS Codice,cognome,nome, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita, (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 1) AS 'PRIMA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 2) AS 'SECONDA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 3) AS 'TERZA', (SELECT voto From tbesiti WHERE idalunno = ksalunno AND ksprova = 4) AS 'ORALE', PRIMA + SECONDA + TERZA + ORALE AS Punteggio FROM tbalunni ORDER BY cognome, nome,datanascita non viene supportata da MySQl, a differenza di Access, in quanto gli ALIAS utilizzati nella target list possono essere richiamati solo dopo la clausola WHERE. Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 12
La query, piuttosto complessa, proposta per risolvere il quesito può far pensare ad una soluzione del problema più semplice. In effetti, tenendo conto che il numero di prove è costante (quattro) e che devono essere comunque sostenute da tutti gli alunni, si potrebbe ricorrere ad un altra soluzione che utilizza una sola entità e quindi una sola tabella. In questo modo la tabella ottenuta si può paragonare ad un foglio elettronico contenente complessivamente tutti i dati di cui si ha bisogno. Di seguito viene presentata questo tipo di soluzione apparentemente più semplice dal punto di vista strutturale (esiste una sola tabella nel database) ma più complicata da gestire a livello di query, soprattutto per le query parametrizzate (query con richiesta di input da parte dell utente utilizzabili, comunque, solo con Access). Come si può notare, con gli esempi proposti successivamente, ci sono query (vedi la n. 18) che sono ragionevolmente più semplici ma la maggior parte sono sicuramente più complesse. Soluzione del problema con una sola tabella Schema concettuale della base di dati Tipi di entità L entità che può essere individuata per risolvere il problema è : Esame contiene l elenco anagrafico degli alunni che sostengono l esame con i corrispondenti risultati ottenuti; Attributi Tipo di entità Esame Sistema informativo Gestione Esami di Stato Attributi Codice alunno, Cognome, Nome, Data di nascita, Crediti, Risultato prima prova, Risultato seconda prova, Risultato terza prova, Risultato orale Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 13
Modello E/R ESAME Schema logico della base di dati Rappresentazione testuale dello schema logico : tbesami (idalunno, cognome, nome, datanascita, crediti, prima, seconda, terza, orale) Definizione della Tabella Tabella Nome campo Chiave Tipo dati Dim. Dec. Null Descrizione tbesami idalunno Primaria Numerico 4 Autoincremento cognome Testo 20 nome Testo 20 datanascita Data/ora 10 cediti Numerico 2 totale credito scolastico prima Numerico 2 Voto prima prova seconda Numerico 2 Voto seconda prova terza Numerico 2 Voto terza prova orale Numerico 2 Voto orale Vengono ora riproposte alcune query significative : Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 14
QUERY Query n. 9) Elenco con descrizione delle prove e la corrispondente media dei voti di tutti gli alunni in ciascuna prova : SELECT AVG(Prima) AS Media_Prima, AVG(Seconda) AS Media_seconda, AVG(Terza) AS Media_terza, AVG(Orale) AS Media_Orale FROM tbesami; Media Prima Media seconda Media terza Media Orale 9,90 11,20 12,10 22,40 Query n. 12) Elenco degli alunni che hanno preso nella SECONDA prova un voto maggiore della media nella stessa prova : SELECT idalunno AS Codice,cognome,nome, seconda FROM tbesami WHERE seconda > (SELECT AVG(seconda) FROM tbesami) ORDER BY cognome,nome; Codice Cognome Nome Seconda 1 BIANCHI ANGELO 12 5 FORNACI ANTONIO 15 6 SOTTOMANO MARCO 15 3 VERDI VITTORIO 15 Nota : non è (?) possibile parametrizzare la query e quindi si dovrebbero scrivere quattro query separate, una per ogni singola prova. Query n. 19) Elenco degli alunni con i voti attribuiti nelle singole prove ed il totale delle prove : SELECT idalunno AS Codice,cognome,nome, DATE_FORMAT(datanascita,'%d-%m-%Y') AS data_nascita, prima, seconda, terza, orale, prima+seconda+terza+orale AS Punteggio FROM tbesami ORDER BY cognome,nome; Es. di analisi di un problema a cura del Prof. Salvatore DE GIORGI - I.T.I.S. FALANTO TALSANO (TA) Pag. 15