Upload
rosaria-gagliardi
View
221
Download
2
Embed Size (px)
Citation preview
SQL: Lezione 8
Nataliya [email protected]
Agenda
AsserzioniTriggerTransazioniConcorrenza
LOCK
JDBC
ASSERZIONI
Grazie alla clausola check è possibile definire anche un ulteriore componente dello schema di una base di dati: le asserzioni.
Le asserzioni rappresentano dei vincoli che non sono associati a nessun attributo o tabella in particolare, ma appartengono direttamente allo schema.
ASSERZIONI
La sintassi per la definizione di un asserzione è:
Un’asserzione può ad esempio imporre che in un ipotetica tabella IMPIEGATO sia sempre presente almeno una riga
La condizione deve essere vera quando viene creata l’asserzione e deve rimanere vera sempre
CREATE ASSERTION NomeAsserzione check(condizione)
CREATE ASSERTION AlmenoUnImpiegato check ((Select count(*) from Impiegato)>=1)
ASSERZIONI
Mediante le asserzioni è possibile esprimere tutti i vincoli che abbiamo specificato nella definizione delle tabelle.
Le asserzioni permetono inoltre di esprimere vincoli che non sarebbero altrimenti definibili, come vincoli su più tabelle o vincoli, ad esempio, che richiedono la cardinalità minima di una tabella.
Le asserzioni possiedono un nome, tramite il quale è possibile eliminarle esplicitamente dallo schema con l’istruzionde drop
ESERCIZIO
Creare un’asserzione che impedisca che esistano presidenti di studi cinematografici che hanno un netWorth inferiore a 100.000 euro.
CREATE ASSERTION "RichPres" CHECK (NOT EXISTS (SELECT * FROM "Studio","MovieExec“ WHERE "presC#"="cert#" AND "netWorth" < 100 000));
Movie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
ESERCIZIO
Creare un’asserzione che impedisca che esistano righe in StarsIn che contengono nomi di attori che non sono presenti nella tabella MovieStarMovie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
CREATE ASSERTION “Star" CHECK (NOT EXISTS (SELECT starName FROM “StarIn“ WHERE starName NOT IN (Select name from MovieStar)));
ESERCIZIO
Per ciascun reparto, con più di 20 impiegati a tempo pieno, (cioè dove le ore degli impiegati a tempo pieno e di quelli part-time assommano almeno a quel numero di ore per impiegati a tempo pieno), visualizzare il rid insieme al numero di impiegati che lavorano in quel reparto.Imp(iid:integer, inome:string, età:integer, salario:real) Rep(rid:integer, budget:real, direttoreid:integer) Lavora(iid:integer, rid:integer, pct_tempo:integer)
SELECT L.rid, COUNT(L.iid) FROM Lavora L GROUP BY L.rid HAVING 3200 < ( SELECT SUM(L1.pct_tempo) FROM Lavora L1 WHERE L1.rid = L.rid)
TRIGGER
I Trigger si basano sul paradigma : EVENTO-CONDIZIONE-AZIONE
Un trigger rappresenta una serie di azioni che sono associate ad un determinato evento, come l’inserimento, la modifica o la cancellazione.
TRIGGER
Funzionamento del trigger si procede in tre passi:
I trigger sono attivati solo quando avvengono determinati eventi (inserzione, modifica, cancellazione)
Invece di impedire immediatamente un evento, il trigger verifica prima una circostanza,
se la circostanza e’ verifica, allora viene eseguita la corrispondente azione dal dbms
TRIGGER
L’azione può essere eseguita prima o dopo l’evento (UPDATE, INSERT, DELETE).
L’azione può essere riferita sia ai vecchi che ai nuovi valori inseriti, cancellati o modificati durante l’evento.
L’evento modifica può essere limitato a un particolare attributo o a un set di attributi
TRIGGER
Un trigger puo’ essere speficicato Di tupla (row-level): attivazione per ogni riga coinvolta
nell’operazione Di operazione (statemente-level) una sola attivazione per
ogni istruzione SQL, con riferimento a tutte le tuple coinvolte
Un trigger puo’ innescare un altro trigger e cosi’ via (sara’ compito del programmatore evitare problemi…)
TRIGGER: Esempio 1
Supponiamo di voler impedire l’abbassamento del valore netto di un produttore:
1 CREATE TRIGGER NetWorthTrigger 2 AFTER UPDATE OF netWorth ON MovieExec 3 REFERENCING OLD ROW AS OldTuple 4 NEW ROW AS NewTuple 5 FOR EACH ROW 6 WHEN (Old.netWorth > NewTuple.netWorth) 7 UPDATE MovieExec SET netWorth = OldTuple.netWorth 8 WHERE cert#=NewTuple.cert#;
1. Parole chiave CREATE TRIGGER2. Evento
3. 4. Le tuple prima e dopo modifica
5. Modalità di trigger
FOR EACH STATEMENT6. Condizione: quando7. 8. Azione
TRIGGER: Esempio 2
Prevenire la situazione quando avg(netWorth)<500000
1 CREATE TRIGGER AvgNetWorthTrigger 2 AFTER UPDATE OF netWorth ON MovieExec 3 REFERENCING OLD TABLE AS OldStuff, 4 NEW TABLE AS NewStuff 5 FOR EACH STATEMENT 6 WHEN (500000 > SELECT AVG(netWorth) FROM MovieExec) 7 BEGIN8 DELETE FROM MovieExec9 WHERE (name, address, cert#, netWorth) IN NewStuff;10 INSERT INTO MovieExec11 (SELECT * FROM OldStuff);12 END;
INSTEAD OF TRIGGER
1 CREATE TRIGGER ParamountInsert 2 INSTEAD OF INSERT ON ParamountMovie 3 REFERENCING NEW ROW AS NewRow 5 FOR EACH ROW 6 INSERT INTO Movie (title, year, studioName)7 VALUES (NewRow.title, NewRow.year, ‘Paramount’)
CREATE VIEW ParamountMovie ASSELECT title, yearFROM MovieWHERE studioName=‘Paramount’
TRANSAZIONI
Una transazione e’ l’esecuzione di un insieme di operazioni di lettura e scrittura di oggetti del db come un tutto indissolubile. Programma di utente in Embedded SQL in C Ovvero CLIENT di DB
Esempi: Prelievo di denaro da un Bancomat Verificare un acquisto con carta di credito Prenotare un libro in libreria
TRANSAZIONI
BEGINInizio del blocco del transazione
COMMITPrima di COMMIT i risultati di operazione possono non
essere visibili alle altre transazioni
ROLLBACKLe modifiche sulla DB si cancellano fino all’ultimo
COMMIT
Aiuta a prevenire i’problemi causati di software/hardware failure
CONCORRENZA: Problema di serialization
Esistono tre situanzioni indesiderabili che possono accadere quando abbiamo transazioni concorrenti:
dirty read Una transazione legge i dati scritti da una transazione
simultanea non commitatanonrepeatable read
Una transazione rilegge dei dati che ha precedentemente letto e li trova modificati da un’atra transizione.
phantom read Una transizione esegue una query che ritorna un set di
righe che soddisfano una condizione e trova che le righe soddisfacenti le condizioni sono state cambiate da un’altra transizione
Esempio: dirty read
Algoritm di transazione di trasferimento di soldi: Aggiungere soldi su conto-destinatario Controllare il conto-mettente
Se i fondi non sono sufficienti, cancellare transazione Se i fondi sono sufficienti, sottrarre la somma dal conto-mittente
A1: 100K, A2:200K, A3:300K, Totale:600K T1 (A1150A2), T2 (A2250A3) – transazioni concorrenti
T1. A2:200+150=350T2. A3:300+250=550
T2. A2:250? SI! Fare trasferimentoT1. A1:150? NO! Cancellare trasferimento
T2. A2:350-250=100T1. A2:100-150=-50
Totale: 600K
CONCORRENZA
User 2
Airline database
Il posto S36 e’ libero?- Si
Il posto S36 e’ libero?- Si
Prenota S36-S36 e’- prenotato per U1
Prenota S36- Attenzione stai prenotando un posto occupato!!
Tim
e
User 1
Esempio: nonrepeatable read
Due utenti (U1 e U2) accedono a un database per la gestione dei voli per prenotare il posto 36 (S36):
U1 controlla se S36 e’ libero ed ottiene un risultato positivo
U2 controlla se S36 e’ libero ed ottiene un risultato positivo
U1 prenota S36 – adesso il posto non e’ piu’ liberoU2 prova a prenotare S36 – ma il posto e’ gia
uccopato
Livello di isolazione
Dirty read in applicazione bancario non è accetabileNonrepeatable read in applicazione di prenotazione
dei biglietti è accettabile
SET TRANSACTION READ WRITEISOLATION LEVEL READ UNCOMMITEDBEGIN TRAN UPDATE Consultants SET HourlyRate = 150 WHERE ConsultantName = 'jacob' ;SELECT * FROM Consultants ;END
Transazione può scrivere
Transazione può leggere i dati non commitati
Ovvero transazione può essere eseguita con un certo livello di isolazione
Isolation Level Dirty Read Nonrepeatable Read Phantom ReadRead uncommitted Possible Possible PossibleRead committed Not possible Possible PossibleRepeatable read Not possible Not possible PossibleSerializable Not possible Not possible Not possible
CONCORRENZA: Livelli di Isolazione
Ci sono 4 livelli di isolazione usati nelle transizioni:
Il livello di isolazione delle transizioni e’ definito tramite:
SET TRANSACTION <isolation level>Nuova transazione non inizia prima di fine della transazione precedente
LOCK
Altra tecnica spesso usata sono i locks (serrature) sui dati condivisi: bloccaggio a livello di comando. tutto il db, una tabella, una tupla, un campo di una
tupla. due transazioni non possono tenere due locks in
conflitto sulla stessa tabella allo stesso tempo. i lock non conflittuali possono essere tenuti
contemporanemante da diverse transizioni.
DEADLOCK
Attenzione ai DeadLocks: e.g., transazione T1 pone un lock sulla tabella A e
richiede la tabella B. Allo stesso tempo, T2 pone un lock su B e richiede A
PostgreSQL risolve automaticamente il deadlock abortendo una delle due transazioni coinvolte
LOCK
Sintassi di base:LOCK [TABLE] name [, ...][IN lockmode MODE]
lockmode può essere ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE
UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
LOCK
Supponiamo di voler incrementare di 100000 euro il valore netto del produttore del film “Meet the Fockers” se il corrente valore e’ minore di 2000000 euro.
Per fare questo e’ necessario:1. Interrogare il db per conoscere il valore del netWorth2. Controllare se il valore è minore di 20000003. Se la condizione e’ vera, incrementare il valore di
100000,
LOCK
Mentre si eseguono i passi 2 e 3, qualsiasi altra transazione potrebbe cambiare il valore di netWorth facendo in modo che che la condizione non sia piu’ vera.
Possiamo bloccare la tabella MovieExec in modo EXCLUSIVE perche’ cio’ non accada
LOCK
BEGIN WORK;
LOCK TABLE imdb."MovieExec" IN EXCLUSIVE MODE;int certNum=SELECT "producerC#" FROM imdb."Movie" WHERE
"title"='Meet the Fockers';
int netWorth=SELECT "netWorth" FROM imdb."MovieExec" WHERE "cert#"=certNum;
if (netWorth<2000000){UPDATE imdb."MovieExec"SET "netWorth"="netWorth"+100000WHERE "cert#"=certNum;}
COMMIT WORK;
JDBC
Java Database Connectivity (JDBC) è un interfaccia per database che consente
l'accesso alle basi di dati da qualsiasi programma scritto con il linguaggio di programmazione JAVA, indipendentemente dal DBMS
JDBC
È costituita da una APIraggruppata nel package java.sql, che serve
ai client per connettersi a un database. Fornisce metodi per interrogare e modificare
le basi di dati.
JDBC
Passi base per usare JDBC : Caricare l’apposito JDBC driver per il db in uso
(PostgreSQL offre differenti driver per diverse versioni del db e di java)
Stabilire una connession con il db Creare uno statement Sottomettere le query al database (il risultato delle
query puo’ essere letto usando la classe ResultSet)
JDBC
Class.forName("org.postgresql.Driver");//locate PostgreSQL JDBC driver
String url = "jdbc:postgresql://" + host + "/" + db;Properties props = new Properties();props.setProperty("user", user);//setting user nameprops.setProperty("password", passwrd);//setting password
Connection con = DriverManager.getConnection(url, props);//getting connection to the database
Statement st = con.createStatement();//creating a statement
ResultSet rs = st.executeQuery(“SELECT * FROM imdb.\"MovieExec\" WHERE \"cert#\"=9713;”);//retrieving query results
Rs.next();//move to the first result row
String name = rs.getString("name");//read name of the producer
Esercizi: Creazione degli schemi
Creare gli schemi per
Product (maker, model, type) PC(model, speed, ram, hd, rd, price) Laptop(model, speed, ram, hd, screen, price) Printer(model, color, type, price)
Classes(class, type, country, numGuns, bore, displacement)
Ships(name, class, launched) Battles(name, date) Outcomes(ship, battle, result)
Esercizi: TRIGGER e/o ASSERTION per PC
When updating PC, check that there is no lower priced PC with the same speed
No manufacturer of a PC’s may also make laptop A manufacturer of a PC must also make a laptop with at least as
great as a processor speed When inserting a new printer, check that the model number exists in
Product table When making any modification to Laptop relation, check that the
average price of laptops for each manufacturer is at least $2000 When updating RAM or hard disk of any PC, check that the updated
PC has at least 100 times as much hard disk as RAM If a laptop has a larger main memory than a PC, then the laptop must
also have a higher price than the PC When inserting a new PC, laptop, or printer, make sure that the
model number did not previously appear in any of PC, Laptop, Printer
If the relation Product mentions a model and its type, then this model must appear in the relation appropriate to that type
Esercizi: TRIGGER e/o ASSERTION per Ships
When a new class is inserted into Classes, also insert a ship with the name of that class and a NULL launch date
When a new class is inserted with a displacement greater than 35000 tons, allow the insertion, but change the displacement to 35000
No class may have more than 2 ships No country may have both battleships and battlecruisers No ship with more than 9 guns may be in a battle with a ship
having fewer than 9 guns that was sunk If a tuple is inserted into Outcomes, check that the ship and battle
are listed in Ships and Battles respectively, and if not, insert tuples into one or both of these relations, with NULL components where necessary
When there is an insertion into Ships oa an update of the “class” attribute of Ships, check that no country has more than 20 ships
No ship may be launched before the ship that bears the name of the first ship’s class
For every class there is a ship with the name of that class
ESERCIZIO
Visualizzare i produttori di film (almeno 1) in cui recitano almeno 10 attori romani.
SELECT MovieExec.name,MovieExec.address FROM Movie,MovieExec WHERE Movie.producerC#=MovieExec.cert# and title in (SELECT title FROM Movie,StarIn,MovieStar WHERE Movie.title=StarsIn.movieTitle and Movie.year=StarsIn.movieYear and MovieStar.name=StarIn.starName and MovieStar.address LIKE ‘%Roma%’ GROUP BY title HAVING COUNT(*)>=10)
Movie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
ESERCIZIO
Visualizzare i nomi degli Studi Cinematografici che hanno prodotto la metà dei propri film in bianco e nero.Movie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
SELECT studioName FROM Movie as M1 WHERE inColor=‘false’ GROUP BY studioName HAVING count(*)= (SELECT count(*) FROM Movie as M2 WHERE inColor=‘true’ and M1.studioName=M2.studioName)
ESERCIZIO
Visualizzare tutti gli attori di sesso femminile che abbiano partecipato a dei film con lunghezza superiore alla durata minima di tutti i film.Movie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
SELECT MovieStar.* FROM MovieStar WHERE gender=‘f’ and name in (SELECT starName FROM StarIn, Movie WHERE movieTitle=title and movieYear=year and length>=(Select Min(length) FROM Movie)
ESERCIZIO
Visualizzare i produttori-attori (persone che hanno recitato nei film da loro stessi prodotti) che vivono a Parigi (Paris).Movie(title,year,length,inColor,studioName,producerC#)StarsIn(movieTitle,movieYear,starName) MovieStar(name,address,gender,birthdate) MovieExec(name,address,cert#,netWorth) Studio(name,address,presC#)
SELECT MovieExec.* FROM MovieExec as M1 WHERE name in (SELECT starName FROM StarIn, Movie WHERE movieTitle=title and movieYear=year and Movie.producerC# =M1.cert#) AND MovieExec.address LIKE ‘%Paris%’
ESERCIZIO
Movie (title, year, length, inColor, studioName, producerC#)StarsIn (movieTitle, movieYear, starName)MovieStar (name, address, gender, birthdate)MovieExec (name, address, cert#, netWorth)Studio (name, address, presC#)
Ricostruire il db relazionale nello schema work, tenendo in considerazione:
Dividere la tabella Movie in 2: MovieColor (con i film a colori) e MovieBW (film in bianco e nero) senza l’attributo INCOLOR.
Nella tabella Studio introdurre un attributo per memorizzare il nome del presidente
Specificare il valore di default per gli attributi quando credete che siano utili.