Memento Chi seguirà il modulo di e-learning? CD di installazione del SW
Esercizio 1 Rappresentazione delle informazioni relative ai partecipanti ad un corso di formazione
Vogliamo memorizzare dati dei partecipanti ad un corso: Esercizio 1 Specifiche Vogliamo memorizzare dati dei partecipanti ad un corso: nome, cognome, data di nascita, se è sposato, e, nel caso lo sia, il numero di figli Vogliamo, poi ricordare le città in cui risiedono e le città in cui sono nati, insieme al numero di abitanti. Per le città capoluogo di regione, vogliamo ricordare la regione Vogliamo poi sapere le lezioni che i partecipanti hanno frequentato, con i (o il) docenti che le hanno svolte, il corrispondente argomento ed il giorno in cui si sono svolte. Ad ogni lezione va associato un numero progressivo. Per i docenti si vuole memorizzare: nome, cognome, e tipo di enti di provenienza Per quelli universitari l’Università da cui provengono e la materia [hp: unica] che insegnano e la città in cui sono è ubicata l’Università
Esercizio 1 Schema ER
Esercizio 1 Vincolo non esprimibile in ER Ogni città è la città di nascita di un partecipante oppure la città di residenza di un partecipante oppure la città in cui è ubicata un’università Citta[Nome] Universita[Citta] Partecipante[CittaResidenza] Partecipante[CittaNascita] Si potrebbe introdurre un’ulteriore generalizzazione
Esercizio 1 Schema logico Lezione(Numero, Data, Argomento) Docente(Nome, Cognome, Ente) Universitario(Nome, Cognome, Ente, Materia, Universita) Universita(Nome, Citta) Citta(Nome, NumAbitanti, Regione) FattaDa(Lezione, NomeDoc, CognomeDoc, EnteDoc) Partecipante(Nome, Cognome,DataNascita, NumFigli, CittaResidenza, CittaNascita) Frequenta(Nome, Cognome, DataNascita, NumLezione)
Esercizio 2 Interrogazioni in SQL
Esercizio 2 Interrogazioni SQL Consideriamo un semplice database relazionale con il seguente schema: Fornitori (F#, Nome, Città) Componenti (C#, Nome, Colore, Peso) Progetti (P#, Nome, Città) Forniture (F#, C#, P#, Quantità) Significato di una tupla della tabella Forniture: Il fornitore “F#” rifornisce il progetto “P#” della componente “C#” nella quantità “Quantità”
Esercizio 2 Interrogazioni SQL Query 1 Elencare in ordine crescente i codici dei fornitori del progetto con codice “P1” Query 2 Elencare le forniture in quantità compresa tra 300 e 750, estremi inclusi Query 3 Elencare i codici delle componenti fornite da fornitori di Londra Query 4 Elencare i codici delle componenti fornite ai progetti da fornitori locali (stessa città del progetto) Query 5 Per ognuna delle componenti fornite ad un progetto, elencare: codice della componente, codice del progetto e corrispondente quantità totale
Esercizio 2 Interrogazioni SQL Query 6 Elencare i colori delle componenti fornite dal fornitore con codice ‘F1’ Query 7 Elencare i codici dei progetti riforniti interamente dal fornitore ‘F1’ Query 8 Elencare i codici dei fornitori che forniscono una stessa componente a tutti i progetti Query 9 Elencare i codici dei fornitori che forniscono tutte le merci fornite dal fornitore ‘F1’ Query 10 Elencare i nomi dei fornitori che forniscono tutte le merci fornite dal fornitore ‘F1’
Query 2: Elencare le forniture in quantità compresa tra 300 e 750 Esercizio 2 Soluzione Query 1: Elencare in ordine crescente i codici dei fornitori del progetto ‘P1’ SELECT DISTINCT F# FROM Forniture WHERE P# = ‘P1’ ORDER BY F# Query 2: Elencare le forniture in quantità compresa tra 300 e 750 SELECT F#, C#, P#, Quantità WHERE Quantità >= 300 AND Quantità <= 750 Query 3: Elencare i codici delle componenti fornite da fornitori di Londra SELECT DISTINCT C# FROM Forniture, Fornitori WHERE Forniture.F# = Fornitori.F# AND Città = ‘Londra’
Esercizio 2 Soluzione Query 4: Elencare i codici delle componenti fornite ai progetti da fornitori locali SELECT DISTINCT C# FROM Forniture, Fornitori, Progetti WHERE Forniture.F# = Fornitori.F# AND Forniture.P# = Progetti.P# AND Fornitori.Città = Progetti.Città Query 5: Per ognuna delle componenti fornite ad un progetto, elencare: codice della componente, codice del progetto e corrispondente quantità totale SELECT C#, P#, SUM (Quantità) FROM Forniture GROUP BY C#, P#
Query 6: Elencare i colori delle componenti fornite dal fornitore ‘F1’ Esercizio 2 Soluzione Query 6: Elencare i colori delle componenti fornite dal fornitore ‘F1’ SELECT DISTINCT Colore FROM Componenti WHERE C# IN ( SELECT C# FROM Forniture WHERE F# = ‘F1’) Query 7: Elencare i codici dei progetti riforniti interamente da ‘F1’ SELECT DISTINCT P# FROM Forniture Ftura1 WHERE NOT EXISTS ( SELECT * FROM Forniture Ftura2 WHERE Ftura2.P# = Ftura1.P# AND Fu2.F# ~= ‘F1’ )
Esercizio 3 Progettare una base di dati per la gestione delle spese di un condominio
Specifiche I Ogni condominio ha un nome che lo identifica e un indirizzo e comprende una più scale cui sono associati più appartamenti Ad ogni scala sono associati un codice che lo identifica insieme al nome del condominio un valore, detto quota della scala, che rappresenta la frazione di spese del condominio (in millesimi) che competono agli appartamenti della scala Ogni appartamento è identificato, nel rispettivo condominio, dalla scala e da un numero (l’interno). Ad ogni appartamento è associata una quota (in millesimi) che indica la frazione delle spese (della scala) che sono di competenza dell’appartamento
Specifiche II Ogni appartamento ha un proprietario per il quale sono di interesse il cognome, il codice fiscale e l’indirizzo al quale deve essere inviata la corrispondenza relativa all’appartamento. Ogni persona ha un solo codice fiscale, ma potendo essere proprietario di più appartamenti potrebbe avere indirizzi diversi per appartamenti diversi. Di solito, anche chi è proprietario di molti appartamenti ha comunque solo uno o pochi indirizzi. In molti casi, l’indirizzo del proprietario coincide con quello del condominio.
Specifiche III Per la parte contabile, è necessario tenere traccia delle spese sostenute dal condominio e dei pagamenti effettuati dai proprietari Ogni spesa è associata ad un intero condominio, oppure ad una scala o un singolo appartamento Ogni pagamento è relativo a uno e un solo appartamento Nella base di dati vengono mantenuti pagamenti e spese relative all’esercizio finanziario in corso (annuale) mentre gli esercizi precedenti vengono sintetizzati attraverso il solo saldo precedente che per ciascun appartamento indica il debito o il credito del proprietario. In ogni istante esiste un saldo corrente per ciascun appartamento, definito come somma algebrica del saldo precedente e dei pagamenti (positivi) e delle spese addebitate (negative).
Il condominio: schema ER Nome Descrizione Codice Indirizzo Data conto condominio (0,N) Spesa Condominio Importo (1,N) (1,1) Composizione Singola Blocco Generale Codice (1,1) (1,1) conto scala (1,1) (0,N) Scala Quota (1,N) Collocazione conto appartamento (1,1) (0,N) Quota Nome Interno Cognome (1,1) CF Data Descrizione Codice (1,1) proprietà (1,N) Appartamento Persona (1,1) saldo (0,N) Importo Pagamento (0,1) Saldo precedente Recapito Saldo corrente Indirizzo
Regole aziendali
Operazioni principali Operazione 1: registrazione di una spesa per un condominio Operazione 2: registrazione di una spesa per una scala Operazione 3: registrazione di una spesa per un appartamento Operazione 4: registrazione di un pagamento Operazione 5: stampa del bilancio di ogni condominio con il totale degli accrediti e degli addebiti per ogni appartamento e calcolo del nuovo saldo Tavola delle operazioni
Carico Tavola dei volumi
Ridondanze Occupazione di memoria Appartamenti x 4 byte = 40000 byte Nome Indirizzo conto condominio (0,N) Occupazione di memoria Appartamenti x 4 byte = 40000 byte Operazioni coinvolte Op. 1: registrazione di una spesa di condominio Op. 2: registrazione di una spesa di scala Op. 3: registrazione di una spesa di appartamento Op. 4: registrazione di un pagamento Op. 5: stampa del bilancio Condominio (1,N) Composizione Codice (1,1) conto scala (0,N) Scala Quota (1,N) Collocazione conto appartamento (0,N) Quota Interno (1,1) Appartamento saldo (0,N) Saldo precedente Saldo corrente
Operazione 1 Op. 1: registra una spesa per un condominio Nome Indirizzo Op. 1: registra una spesa per un condominio conto condominio (0,N) Condominio (1,N) Composizione Codice (1,1) conto scala (0,N) Scala Quota (1,N) Collocazione conto appartamento (0,N) con ridondanza Quota Interno (1,1) Appartamento saldo (0,N) Saldo precedente Saldo corrente senza ridondanza
Operazione 2 Op. 2: registra una spesa per una scala con ridondanza Codice (1,1) conto scala (0,N) Scala Quota (1,N) Collocazione conto appartamento (0,N) Quota Interno (1,1) con ridondanza Appartamento saldo (0,N) Saldo precedente Saldo corrente senza ridondanza
Operazione 3 Op. 3: registra una spesa per un appartamento conto appartamento (0,N) Quota Interno (1,1) Appartamento saldo (0,N) con ridondanza Saldo precedente Saldo corrente senza ridondanza
Operazione 4 Op. 4: registra un pagamento con ridondanza Quota Interno (1,1) Appartamento saldo (0,N) con ridondanza Saldo precedente Saldo corrente senza ridondanza
Operazione 5 con ridondanza Op. 5: calcolo del bilancio conto Nome Indirizzo Op. 5: calcolo del bilancio conto condominio (0,N) Condominio (1,N) Composizione Codice (1,1) conto scala (0,N) Scala Quota (1,N) Collocazione conto appartamento (0,N) con ridondanza Quota Interno (1,1) Appartamento saldo (0,N) Saldo precedente Saldo corrente
Operazione 5 senza ridondanza Op. 5: calcolo del bilancio conto Nome Op. 5: calcolo del bilancio Indirizzo conto condominio (0,N) Condominio (1,N) Composizione Codice (1,1) conto scala (0,N) Scala Quota (1,N) Collocazione conto appartamento (0,N) Quota Interno (1,1) Appartamento saldo (0,N) Saldo precedente senza ridondanza Saldo corrente
Scelta ridondanza Totali con ridondanza senza ridondanza Risulta evidente che conviene rimuovere la ridondanza!
Gerarchie Descrizione Descrizione Codice Codice Data Data (1,1) conto condominio Spesa Generale Spesa Importo Importo conto condominio Descrizione Codice (1,1) Singola Blocco Generale Data conto scala Spesa Blocco (1,1) Importo conto scala (1,1) Descrizione Codice Data conto appartamento Spesa singola (1,1) Importo conto appartamento (1,1) Tutte le operazioni distinguono i tre sottotipi di Spesa e quindi conviene eliminare la gerarchia eliminando il padre e riportando tutti gli attributi nelle figlie
Schema ristrutturato Descrizione Codice Nome Sono stati introdotti identificatori ad hoc (Id) per non usare chiavi complesse nel collegamento delle tabelle (chiavi composte o basate su stringhe) Indirizzo Id Data (1,1) conto condominio Spesa Generale (0,N) Condominio Importo (1,N) Composizione Descrizione Codice Id Codice Data (1,1) conto scala Spesa Blocco (1,1) (0,N) Scala Quota Importo Descrizione (1,N) Codice Data Collocazione conto appartamento Spesa singola (1,1) (0,N) Importo Quota Interno Nome Cognome (1,1) CF Id Id Data Descrizione Codice (1,1) proprietà (1,N) Appartamento Persona (1,1) saldo (0,N) Importo Pagamento (0,1) Saldo precedente Recapito Indirizzo
Schema relazionale Condomini Scale Appartamenti Recapiti Persone Nome Indirizzo Id Condominio Condomini (1,N) Composizione Scale Id Codice (1,1) Scala Quota Appartamenti (1,N) Collocazione Recapiti Quota Interno Nome Cognome (1,1) CF Id Id (1,1) (1,N) proprietà Appartamento Persona (0,1) Saldo precedente Recapito Persone Indirizzo
Schema relazionale Condomini Scale Appartamenti Pagamenti Descrizione Nome Condomini Data Codice Indirizzo Id (1,1) conto condominio (0,N) Spesa Generale Condominio Scale (1,N) Importo Composizione Data Descrizione Codice Quota Id Appartamenti (1,1) (1,1) conto scala (0,N) Spesa Blocco Scala (1,N) Pagamenti Descrizione Importo Data Codice Codice Collocazione conto appartamento Spesa singola (1,1) Interno Spese_singole (1,1) Id (0,N) Importo Appartamento Descrizione Data Codice Spese_blocco (0,N) (1,1) saldo Quota Pagamento Saldo precedente Importo Spese_generali
Creazione delle tabelle SQL create schema condomini set schema condomini create table condomini ( id smallint not null primary key, nome varchar(20) not null unique, indirizzo varchar(50)) create table scale ( id smallint not null primary key, codice char(1) not null, condominio smallint not null references condomini(id), quota smallint not null, unique(codice,condominio)) create table persone ( id integer not null primary key, nome varchar(15) not null, cognome varchar(15) not null, CF char(16))
Creazione delle tabelle SQL II create table recapiti ( id integer not null primary key, indirizzo varchar(50) not null) create table appartamenti ( id integer not null primary key, interno char(4) not null, scala smallint not null references scale(id), proprietario smallint not null references persone(id), recapito smallint references recapiti(id), quota smallint not null, saldo decimal(6,2) not null, unique(interno,scala))
Creazione delle tabelle SQL III create table pagamenti ( codice integer not null primary key, data date not null, descrizione varchar(1000), importo decimal(7,2) not null, appartamento integer not null references appartamenti(id)) create table spesa_generale ( codice integer not null primary key, data date not null, descrizione varchar(1000), importo decimal(7,2) not null, condominio integer not null references condomini(id)) create table spesa_blocco ( codice integer not null primary key, data date not null, descrizione varchar(1000), importo decimal(7,2) not null, scala integer not null references scale(id))
Creazione delle tabelle SQL IV create table spesa_singola ( codice integer not null primary key, data date not null, descrizione varchar(1000), importo decimal(7,2) not null, appartamento integer not null references appartamenti(id))
Operazioni Op. 1: registra una spesa per un condominio insert into spesa_generale(codice,data,descrizione, importo,condominio) values ((select max(codice)+1 from spesa_generale), :data, :descrizione,:importo, (select id from condomini where nome=:nome)) Op. 2: registra una spesa per una scala insert into spesa_blocco(codice,data,descrizione, importo,scala) values ((select max(codice)+1 from spesa_blocco), :data, :descrizione,:importo, (select scale.id from scale, condomini where condomini.nome=:nome and scale.codice=:codice and scale.condominio=condomini.id))
Operazioni Op. 3: registra una spesa per un appartamento insert into spesa_singola(codice,data,descrizione, importo,appartamento) values ((select max(codice)+1 from spesa_singola), :data, :descrizione,:importo, (select appartamenti.id from scale,condomini,appartamenti where condomini.nome=:nome and scale.codice=:codice and appartamenti.interno=:interno and scale.condominio=condomini.id and appartamenti.scala=scale.id))
Operazioni Op. 4: registra un pagamento insert into pagamenti(codice,data,descrizione, importo,appartamento) values ((select max(codice)+1 from pagamenti), :data, :descrizione,:importo, (select appartamenti.id from scale,condomini,appartamenti where condomini.nome=:nome and scale.codice=:codice and appartamenti.interno=:interno and scale.condominio=condomini.id and appartamenti.scala=scale.id))
Operazioni Op. 5: calcola bilancio create view bilancio_condominio(id,bilancio) as select id, sum(importo)from condomini, spese_generali where condomini.id=spese_generali.condominio group by id create view tot_spese_blocco(id,tot) as select scale.id, sum(importo) from scale, spese_blocco where scale.id=spese_blocco.scala group by scale.id create view parte_scale_in_cond(id,tot) as select scale.id, bilancio*quota/1000 from scale,bilancio_condominio where scale.condominio= bilancio_condominio.id create view bilancio_scale(id,bilancio) as select tsb.id,tsb.tot + psic.tot from tot_spese_blocco as tsb, parte_scale_in_cond as psic where tsb.id= psic.id
Operazioni create view tot_spese_singole(id,tot) as select appartamenti.id, sum(importo) from appartamenti, spese_appartamento where appartamenti.id=spese_blocco.appartamento group by appartamenti.id create view parte_app_in_scale(id,tot) as select appartamenti.id, bilancio*quota/1000 from appartamenti,bilancio_scale where appartamenti.scala=bilancio_scale.id create view tot_spese_appartamento(id,codice,tot) as select tss.id, tss.tot + pais.tot from tot_spese_singole as tss, parte_app_in_scale as pais where tss.id= pais.id create view tot_pag_appartamento(id,interno,tot) as select appartamenti.id, interno, sum(importo) from appartamenti, pagamenti where appartamenti.id=pagamenti.appartamento group by appartamenti.id, interno
Operazioni create view bilancio(condominio, scala, interno, crediti, debiti,saldo_precedente,nuovo_saldo) as select condominio.nome, scala.codice, appartamenti.interno, pagamenti.tot, spese.tot, appartamenti.saldo, appartamenti.saldo + pagamenti.tot - spese.tot from condomini, scale, appartamenti, tot_spese_appartamento as spese, tot_pag_appartamento as pagamenti where appartamenti.scala=scale.id and scale.condominio=condomini.id and spese.id=appartamenti.id and pagamenti.id=appartamenti.id order by condomini.nome, scale.codice, appartamenti.interno