Verifica di Informatica Cognome e Nome: Classe 5ª Ci, Data Progettare la base di dati di una palestra. E necessario memorizzare le informazioni relative ai clienti che riguardano: codice fiscale, cognome e nome, indirizzo, età e numero telefonico. Ogni cliente deve avere un certificato di sana e robusta costituzione prima di cominciare l attività fisica, pertanto, occorre assegnare a ciascuno un appuntamento con uno dei medici sportivi che seguono la palestra. Il cliente potrà iscriversi, in periodi differenti, ai vari corsi proposti, quindi una sola tra queste iscrizioni sarà attiva. Dei corsi proposti è noto il nome e l istruttore. Mentre per ogni iscrizione si memorizzi la situazione dei pagamenti cioè il costo complessivo per l iscrizione al corso e l elenco di tutte le rate pagate e non pagate con la relativa data di scadenza. Inoltre, per ogni iscrizione si memorizzino anche gli esercizi che il cliente deve eseguire per rispettare il programma assegnatogli. Di ogni esercizio si conosce il nome, il muscolo principale coinvolto, le controindicazioni e, per ogni cliente, il numero di ripetizioni da eseguire. Della suddetta realtà, dopo aver precisato le ipotesi aggiuntive, ritenute opportune, si realizzi: Un analisi della situazione sopra descritta che illustri le premesse per i successivi passi della progettazione della base di dati. La definizione dello schema concettuale mediante un diagramma Entità-Relazione. La definizione dello schema relazionale della base di dati. La definizione degli script SQL per la creazione fisica della base di dati. L implementazione delle seguenti interrogazioni espresse nel linguaggio SQL: 1. L elenco delle rate che ogni cliente deve pagare ordinato per cognome e nome e per data di scadenza della rata. 2. Il numero di iscrizioni che si sono avute in un determinato anno raggruppando per i vari corsi. 3. L elenco riportante il totale delle rate da pagare, superiori a 500, dettagliando il risultato sui singoli corsi. 4. L elenco dei clienti con età superiore all età di tutti i clienti iscritti al corso di Body Building. 5. Riportare le informazioni relative ai corsi a cui sono iscritti clienti che eseguono un programma con più di 10 esercizi. 6. L elenco dei clienti che non eseguono l esercizio chiamato piegamenti con numero di ripetizioni pari a 5. 7. L elenco riportante per ogni cliente il costo totale dell iscrizione al corso frequentato e il totale delle rate da pagare.
Soluzione: Progettazione Concettuale: Modello Entità-Relazione. Progettazione Logica: Schema Relazionale. Fig. 1: Modello Entità-Relazione MediciIDMedico, Cognome, Nome VisiteIDClienteFK, IDMedicoFK, DataVisita ClientiIDCliente, Cognome, Nome, CF, Indirizzo, Telefono, Eta IscrizioniIDIscrizione, Dal, Al, Attiva, CostoTotale, IDClienteFK, IDCorsoFK CorsiIDCorso, Nome, Istruttore ProgrammiIDIscrizioneFK, IDEsercizioFK, NumeroRipetizioni RateIDRata, DataPagamento, Importo, Pagata, DataScadenza, IDIscrizioneFK EserciziIDEsercizio, Nome, Muscolo, Controindicazione Attenzione in questo caso la relazione molti a molti è stata tratta diversamente dagli esercizi precedenti: la chiave primaria è costituita dalle due chiavi primarie delle tabelle coinvolte nella relazione, con i relativi vincoli di FK.
Fig. 2: Schema Relazionale. Implementazione Fisica: Script SQL di creazione Create table [Medici] [IDMedico] Integer NOT NULL, [Nome] Varchar50 NULL, [Cognome] Varchar50 NULL, Constraint [pk_medici] Primary Key [IDMedico] /*e un modo alternativo per definire le pk*/ Create table [Clienti] [IDCliente] Integer NOT NULL, [Cognome] Varchar50 NULL, [Nome] Char10 NULL, [CF] Char10 NULL, [Indirizzo] Char10 NULL, [Telefono] Char10 NULL, [Eta] Integer NULL, Constraint [pk_clienti] Primary Key [IDCliente] Create table [Iscrizioni] [IDIscrizione] Integer NOT NULL,
[Dal] Datetime NULL, [Al] Datetime NULL, [CostoTotale] Money NULL, [Attiva] Char10 NULL, [IDCorso] Integer NOT NULL, [IDCliente] Integer NOT NULL, Constraint [pk_iscrizioni] Primary Key [IDIscrizione] Create table [Corsi] [IDCorso] Integer NOT NULL, [Nome] Char10 NULL, [Istruttore] Char10 NULL, Constraint [pk_corsi] Primary Key [IDCorso] Create table [Rate] [IDRata] Integer NOT NULL, [Importo] Money NULL, [Pagata] Bit NULL, [DataScadenza] Datetime NULL, [DataPagamento] Datetime NULL, [IDIscrizione] Integer NOT NULL, Constraint [pk_rate] Primary Key [IDRata] Create table [Esercizi] [IDEsercizio] Integer NOT NULL, [Nome] Char10 NULL, [Muscolo] Char10 NULL, [Controindicazioni] Char10 NULL, Constraint [pk_esercizi] Primary Key [IDEsercizio] Create table [Programmi] [IDIscrizione] Integer NOT NULL, [IDEsercizio] Integer NOT NULL, [NumeroRipetizioni] Integer NULL, Constraint [pk_programmi] Primary Key [IDIscrizione],[IDEsercizio] Create table [Visite] [IDCliente] Integer NOT NULL, [IDMedico] Integer NOT NULL, [DataVisita] Datetime NULL, Constraint [pk_visite] Primary Key [IDCliente],[IDMedico] Alter table [Visite] add Constraint [FK_Medici_Visite_IDMedico] foreign key[idmedico] references [Medici] [IDMedico] Alter table [Iscrizioni] add Constraint [FK_Clienti_Iscrizioni_IDCliente] foreign key[idcliente] references [Clienti] [IDCliente] Alter table [Visite] add Constraint [FK_Clienti_Visite_IDCliente] foreign key[idcliente] references [Clienti] [IDCliente] Alter table [Rate] add Constraint [FK_Iscrizioni_Rate_IDIscrizione] foreign key[idiscrizione] references [Iscrizioni] [IDIscrizione]
Alter table [Programmi] add Constraint [FK_Iscrizioni_Programmi_IDIscrizioni] foreign key[idiscrizione] references [Iscrizioni] [IDIscrizione] Alter table [Iscrizioni] add Constraint [FK_Corsi_Iscrizioni_IDCorso] foreign key[idcorso] references [Corsi] [IDCorso] Alter table [Programmi] add Constraint [FK_Esercizi_Programmi_IDEsercizio] foreign key[idesercizio] references [Esercizi] [IDEsercizio] In aggiunta è riportato lo script di creazione di un indice sulla tabella clienti per velocizzare le ricerche per cognome e nome: CREATE INDEX IX_Clienti_Cognome_Nome ON ClientiCognome,Nome Inoltre è aggiunto un vincolo Constraint sui valori assunti dalle date di iscrizione ad un corso: Al deve essere maggiore di Dal. ALTER TABLE Iscrizioni ADD CONSTRAINT CK_Iscrizioni_Date CHECK Al>=Dal Per finire è riportato lo script di creazione di una vista che riporta per ogni iscrizione il nome del corso e il cliente relativo: Create VIEW [ClientiIscrizioniCorsi] AS SELECT Corsi.IDCorso, Corsi.Nome AS NomeCorso, Corsi.Istruttore, Iscrizioni.IDIscrizione, Iscrizioni.Dal, Iscrizioni.Al, Iscrizioni.CostoTotale, Iscrizioni.IDCliente, Iscrizioni.Attiva, Clienti.Cognome, Clienti.Nome AS NomeCliente, Clienti.CF, Clienti.Indirizzo, Clienti.Telefono, Clienti.Eta FROM Corsi INNER JOIN Iscrizioni ON Corsi.IDCorso = Iscrizioni.IDCorso INNER JOIN Clienti ON dbo.iscrizioni.idcliente = Clienti.IDCliente Fig. 3: Schema Relazionale in MS SQL Server 2005
Interrogazioni. 1. SELECT Clienti.Cognome, Clienti.Nome, Iscrizioni.IDCorso, Iscrizioni.Dal, Iscrizioni.Al, Rate.IDRata, Rate.Importo, Rate.DataScadenza FROM Clienti INNER JOIN Iscrizioni ON Clienti.IDCliente = Iscrizioni.IDCliente INNER JOIN Rate ON Iscrizioni.IDIscrizione = Rate.IDIscrizione WHERE Iscrizioni.Attiva = 1 ORDER BY Clienti.Cognome, Clienti.Nome, Rate.DataScadenza 2. SELECT COUNT* NumeroIscrizione, Corsi.Nome FROM Corsi INNER JOIN Iscrizioni ON Corsi.IDCorso = Iscrizioni.IDCorso GROUP BY Corsi.Nome 3. SELECT SUMRate.Importo ImportoTotale,Corsi.Nome FROM Corsi INNER JOIN Iscrizioni ON Corsi.IDCorso = Iscrizioni.IDCorso INNER JOIN Rate ON Iscrizioni.IDIscrizione = Rate.IDIscrizione GROUP BY Corsi.Nome HAVING SUMRate.Importo>500 4. SELECT * FROM Clienti WHERE eta > ALL SELECT Clienti.eta FROM Clienti INNER JOIN Iscrizioni ON Clienti.IDCliente = Iscrizioni.IDCliente INNER JOIN Corsi ON Iscrizioni.IDCorso = Corsi.IDCorso WHERE Iscrizioni.Attiva = 1 AND Corsi.Nome='Body Building' 5. SELECT * FROM Corsi WHERE IDCorso IN SELECT DISTINCT IDCorso FROM Iscrizioni WHERE IDIscrizione IN SELECT IDIscrizione FROM dbo.programmi GROUP BY IDIscrizione HAVING COUNT* > 10 6. SELECT * FROM Clienti WHERE Clienti.IDCliente NOT IN SELECT Iscrizioni.IDCliente FROM Iscrizioni INNER JOIN Programmi ON Iscrizioni.IDIscrizione = Programmi.IDIscrizione INNER JOIN Esercizi ON Esercizi.IDEsercizio=Programmi.IDEsercizio WHERE Iscrizioni.Attiva=1 AND Esercizi.Nome='Piegamenti' AND Programmi.NumeroRipetizioni=5
7. SELECT Clienti.Cognome,Clienti.Nome,Iscrizioni.IDIscrizione, Tab.TotaleRateDaPagare,Iscrizioni.CostoTotale FROM Iscrizioni INNER JOIN Clienti ON Iscrizioni.IDCliente = Clienti.IDCliente INNER JOIN SELECT SUMRate.Importo TotaleRateDaPagare, Rate.IDIscrizione FROM Rate WHERE Rate.Pagata=0 GROUP BY Rate.IDIscrizione Tab ON Iscrizioni.IDIscrizione=Tab.IDIscrizione WHERE Iscrizioni.Attiva=1