Il linguaggio SQL: viste e tabelle derivate Sistemi Informativi T Versione elettronica: 04.5.SQL.viste.pdf D di riferimento per gli esempi Imp Sedi CodImp 00 00 003 Nome Rossi Verdi ianchi Sede S0 S0 S0 Ruolo nalista Sistemista Programmatore Stipendio 000 500 000 Sede S0 S0 S03 Responsabile iondi Mori Fulvi Citta Milano ologna Milano 004 Gialli S03 Programmatore 000 005 006 007 008 Neri Grigi Violetti ranci S0 S0 S0 S0 nalista Sistemista Programmatore Programmatore 500 00 000 00 Prog CodProg P0 P0 Citta Milano ologna P0 ologna SQL: viste Sistemi Informativi T
Definizione di viste Mediante l istruzione CRT VIW si definisce una vista, ovvero una tabella virtuale Le tuple della vista sono il risultato di una query che viene valutata dinamicamente ogni volta che si fa riferimento alla vista ProgSedi CRT VIW ProgSedi(CodProg,CodSede) S SLCT P.CodProg,S.Sede FROM Prog P, Sedi S WHR P.Citta = S.Citta SLCT * FROM ProgSedi WHR CodProg = P0 CodProg P0 P0 P0 CodSede SQL: viste Sistemi Informativi T 3 S0 S03 S0 CodProg P0 P0 P0 P0 CodSede S0 S03 S0 S0 Uso delle viste Le viste possono essere create a vari scopi, tra i quali si ricordano i seguenti: Permettere agli utenti di avere una visione personalizzata del D, e che in parte astragga dalla struttura logica del D stesso Far fronte a modifiche dello schema logico che comporterebbero una ricompilazione dei programmi applicativi Semplificare la scrittura di query complesse Inoltre le viste possono essere usate come meccanismo per il controllo degli accessi, fornendo ad ogni classe di utenti gli opportuni privilegi Si noti che nella definizione di una vista si possono referenziare anche altre viste SQL: viste Sistemi Informativi T 4
Indipendenza logica tramite VIW titolo esemplificativo si consideri un D che contiene la tabella samisit(matr,cognome,nome,dataprova,voto) Per evitare di ripetere i dati anagrafici, si decide di modificare lo schema del D sostituendo alla tabella samisit le due seguenti: StudentiSIT(Matr,Cognome,Nome) ProveSIT(Matr,DataProva,Voto) È possibile ripristinare la visione originale in questo modo: CRT VIW samisit(matr,cognome,nome,dataprova,voto) S SLCT S.*,P.DataProva,P.Voto FROM StudentiSIT S, ProveSIT P WHR S.Matr = P.Matr SQL: viste Sistemi Informativi T 5 Query complesse che usano VIW () Un classico esempio di uso delle viste si ha nella scrittura di query di raggruppamento in cui si vogliono confrontare i risultati della funzione aggregata La sede che ha il massimo numero di impiegati La soluzione senza viste è: SLCT I.Sede FROM Imp I GROUP Y I.Sede HVING COUNT(*) >= LL (SLCT COUNT(*) FROM Imp I GROUP Y I.Sede) SQL: viste Sistemi Informativi T 6 3
Query complesse che usano VIW () La soluzione con viste è: CRT VIW NumImp(Sede,Nimp) S SLCT Sede, COUNT(*) FROM Imp GROUP Y Sede SLCT Sede FROM NumImp WHR Nimp = (SLCT MX(NImp) FROM NumImp) NumImp Sede NImp S0 4 S0 3 S03 che permette di trovare il MX dei COUNT(*), cosa che, si ricorda, non si può fare direttamente scrivendo MX(COUNT(*)) SQL: viste Sistemi Informativi T 7 Query complesse che usano VIW (3) Con le viste èinoltre possibile risolvere query che richiedono piu passi di raggruppamento, ad es: Per ogni valore (arrotondato) di stipendio medio, numero delle sedi che pagano tale stipendio Occorre aggregare prima per sede, poi per valore di stipendio medio CRT VIW StipSedi(Sede,vgStip) S SLCT Sede, VG(Stipendio) FROM Imp GROUP Y Sede StipSedi Sede vgstip S0 75 S0 733 S03 000 SLCT vgstip, COUNT(*) S NumSedi vgstip NumSedi FROM StipSedi 75 GROUP Y vgstip 733 000 SQL: viste Sistemi Informativi T 8 4
ggiornamento di viste Le viste possono essere utilizzate per le interrogazioni come se fossero tabelle del D, ma per le operazioni di aggiornamento ci sono dei limiti CRT VIW NumImp(Sede,NImp) S SLCT Sede,COUNT(*) FROM Imp GROUP Y Sede NumImp Sede NImp S0 4 S0 3 S03 UPDT NumImp ST NImp = NImp + WHR Sede = S03 Cosa significa? Non si può fare! SQL: viste Sistemi Informativi T 9 ggiornabilità di viste () Una vista èdi fatto una funzione che calcola un risultato y a partire da un istanza di database r, y = V(r) L aggiornamento di una vista, che trasforma y in y, può essere eseguito solo se è univocamente definita la nuova istanza r tale che y = V(r ), e questo corrisponde a dire che la vista è invertibile, ossia r = V (y ) Data la complessità del problema, di fatto ogni DMS pone dei limiti su quelle che sono le viste aggiornabili Le più comuni restrizioni riguardano la non aggiornabilità di viste in cui il blocco più esterno della query di definizione contiene: GROUP Y Funzioni aggregate DISTINCT join (espliciti o impliciti) SQL: viste Sistemi Informativi T 0 5
ggiornabilità di viste () La precisazione che è il blocco più esterno della query di definizione che non deve contenere, ad es., dei join ha importanti conseguenze. d esempio, la seguente vista non è aggiornabile CRT VIW ImpO(CodImp,Nome,Sede,Ruolo,Stipendio) S SLCT I.* FROM Imp I JOIN Sedi S ON (I.Sede = S.Sede) WHR S.Citta = ologna mentre lo èquesta, di fatto equivalente alla prima CRT VIW ImpO(CodImp,Nome,Sede,Ruolo,Stipendio) S SLCT I.* FROM Imp I WHR I.Sede IN (SLCT S.Sede FROM Sedi S WHR S.Citta = ologna ) SQL: viste Sistemi Informativi T Viste con CHCK OPTION () Per le viste aggiornabili si presenta un nuovo problema. Si consideri il seguente inserimento nella vista ImpO INSRT INTO ImpO(CodImp,Nome,Sede,Ruolo,Stipendio) VLUS ( 009, zzurri, S03, nalista,800) in cui il valore di Sede ( S03 ) non rispetta la specifica della vista. Ciò comporta che una successiva query su ImpO non restituirebbe la tupla appena inserita (!?) Per evitare situazioni di questo tipo, all atto della creazione di una vista si può specificare la clausola WITH CHCK OPTION, che garantisce che ogni tupla inserita nella vista sia anche restituita dalla vista stessa SQL: viste Sistemi Informativi T 6
Viste con CHCK OPTION () CRT VIW ImpO(CodImp,Nome,Sede,Ruolo,Stipendio) S SLCT I.* FROM Imp I WHR I.Sede IN (SLCT S.Sede FROM Sedi S WHR S.Citta = ologna ) WITH CHCK OPTION In questo modo l inserimento INSRT INTO ImpO(CodImp,Nome,Sede,Ruolo,Stipendio) VLUS ( 009, zzurri, S03, nalista,800) viene impedito SQL: viste Sistemi Informativi T 3 Tipi di CHCK OPTION () Si presenta spesso il caso in cui una vista V sia definita in termini di un altra vista V, magari a sua volta definita in termini di altre viste, ecc. Se si crea V specificando la clausola WITH CHCK OPTION, il DMS verifica che la nuova tupla t inserita soddisfi sia la definizione di V che quella di V (e di tutte le altre eventuali viste da cui V dipende), indipendentemente dal fatto che V sia stata a sua volta definita WITH CHCK OPTION Questo comportamento di default èequivalente a definire V WITH CSCDD CHCK OPTION Lo si può alterare definendo V WITH LOCL CHCK OPTION Ora il DMS verifica solo che t soddisfi la specifica di V e quelle di tutte e sole le viste da cui V dipende per cui è stata specificata la clausola WITH CHCK OPTION SQL: viste Sistemi Informativi T 4 7
Tipi di CHCK OPTION () Si consideri il seguente grafo di dipendenze tra views e tables: V3 V4 Vista Definita come V WITH CHCK OPTION V V V V3 WITH LOCL CHCK OPTION R V4 WITH CHCK OPTION La tabella riassume le definizioni di quali viste vengono verificate quando si inserisce una tupla in una data vista INSRT INTO V V V3 V4 Si controllano V,V3 V,V,V4 SQL: viste Sistemi Informativi T 5 V Table expressions () Tra le caratteristiche più interessanti di SQL vi èla possibilità di usare all interno della clausola FROM una subquery che definisce dinamicamente una tabella derivata, e che qui viene anche detta table expression Per ogni sede, lo stipendio massimo e quanti impiegati lo percepiscono SLCT SM.Sede,SM.MaxStip,COUNT(*) S NumImpWMaxStip FROM Imp I,(SLCT Sede, MX(Stipendio) FROM Imp GROUP Y Sede) S SM(Sede,MaxStip) WHR I.Sede = SM.Sede SM ND I.Stipendio = SM.MaxStip Sede MaxStip GROUP Y SM.Sede,SM.MaxStip S0 000 S0 500 S03 000 SQL: viste Sistemi Informativi T 6 8
Table expressions () nche le table expressions possono essere usate per query che richiedono diversi passi di aggregazione Per ogni valore (arrotondato) di stipendio medio, numero delle sedi che pagano tale stipendio SLCT vgstip, COUNT(*) S NumSedi FROM (SLCT Sede, VG(Stipendio) FROM Imp GROUP Y Sede) S StipSedi(Sede,vgStip) GROUP Y vgstip SQL: viste Sistemi Informativi T 7 Table expressions correlate () Una table expression può essere correlata a un altra tabella che la precede nella clausola FROM In D è necessario utilizzare la parola riservata TL o LTRL Per ogni sede, la somma degli stipendi pagati agli analisti SLCT S.Sede,Stip.TotStip FROM Sedi S, TL(SLCT SUM(Stipendio) FROM Imp I WHR I.Sede = S.Sede ND I.Ruolo = nalista ) S Stip(TotStip) Si noti che sedi senza analisti compaiono in output con valore nullo per TotStip. Usando il GROUP Y lo stesso risultato si potrebbe ottenere con un LFT OUTR JOIN, ma occorre fare attenzione SQL: viste Sistemi Informativi T 8 9
Table expressions correlate () Per ogni sede, il numero di analisti e la somma degli stipendi ad essi pagati SLCT S.Sede,Stip.Numn,Stip.TotStip FROM Sedi S, TL(SLCT COUNT(*),SUM(Stipendio) FROM Imp I WHR I.Sede = S.Sede ND I.Ruolo = nalista ) S Stip(Numn,TotStip) Per sedi senza analisti Numn vale 0 e TotStip è nullo. Viceversa SLCT S.Sede,COUNT(*) S Numn,SUM(Stipendio) S TotStip FROM Sedi S LFT OUTR JOIN Imp I ON (I.Sede = S.Sede) ND (I.Ruolo = nalista ) GROUP Y S.Sede ha per le sedi senza analisti TotStip nullo, ma Numn pari a! (in quanto per ognuna di tali sedi c è una tupla nel risultato dell outer join). È quindi necessario usare, ad esempio, COUNT(CodImp) SQL: viste Sistemi Informativi T 9 Limiti delle table expressions Si consideri la query La sede in cui la somma degli stipendi è massima La soluzione con table expressions è SLCT Sede FROM (SLCT Sede,SUM(Stipendio) S TotStip FROM Imp GROUP Y Sede) S SediStip WHR TotStip = (SLCT MX(TotStip) FROM (SLCT Sede,SUM(Stipendio) S TotStip FROM Imp GROUP Y Sede) S SediStip) enché la query sia corretta, non viene sfruttato il fatto che le due table expressions sono identiche, il che porta a una valutazione inefficiente e a una formulazione poco leggibile SQL: viste Sistemi Informativi T 0 0
Common table expressions L idea alla base delle common table expressions è definire una vista temporanea che può essere usata in una query come se fosse a tutti gli effetti una VIW WITH SediStip(Sede,TotStip) S (SLCT Sede,SUM(Stipendio) FROM Imp GROUP Y Sede) SLCT Sede FROM SediStip WHR TotStip = (SLCT MX(TotStip) FROM SediStip) Nel caso generale la clausola WITH supporta la definizione di più c.t.e.: WITH CT(...) S (...), CT(...) S (...)... SQL: viste Sistemi Informativi T WITH e interrogazioni ricorsive () Si consideri la tabella Genitori(Figlio,Genitore) e la query Trova tutti gli antenati (genitori, nonni, bisnonni, ) di nna La query è ricorsiva e pertanto non è esprimibile in algebra relazionale, in quanto richiede un numero di (self )join non noto a priori La formulazione mediante common table expressions definisce la vista temporanea (ricorsiva) ntenati(persona,vo) facendo l unione di: una subquery base non ricorsiva (che inizializza ntenati con le tuple di Genitori) una subquery ricorsiva che ad ogni iterazione aggiunge ad ntenati le tuple che risultano dal join tra Genitori e ntenati Genitori ntenati ntenati ntenati Figlio nna Luca Luca Giorgio Genitore Luca Maria Giorgio Persona nna Luca Luca vo Luca Maria Giorgio Persona vo + nna Maria + nna Lucia Lucia Giorgio Lucia SQL: viste Sistemi Informativi T Luca Giorgio Persona nna vo Lucia
WITH e interrogazioni ricorsive () WITH ntenati(persona,vo) S ((SLCT Figlio, Genitore -- subquery base FROM Genitori) UNION LL -- sempre UNION LL! (SLCT G.Figlio,.vo -- subquery ricorsiva FROM Genitori G, ntenati WHR G.Genitore =.Persona)) SLCT vo FROM ntenati WHR Persona = nna SQL: viste Sistemi Informativi T 3 WITH e interrogazioni ricorsive (3) Per capire meglio come funziona la valutazione di una query ricorsiva, e come ci si ferma, si tenga presente che ad ogni iterazione il DMS aggiunge ad ntenati le tuple che risultano dal join tra Genitori e le sole tuple aggiunte ad ntenati al passo precedente Genitori ntenati Figlio Genitore subquery base Persona vo nna Luca nna Luca Luca Maria subquery ricorsiva Luca Maria Luca Giorgio Luca Giorgio Giorgio Lucia Giorgio Lucia nna Maria nna Giorgio Luca Lucia nna Lucia SQL: viste Sistemi Informativi T 4
Tipi notevoli di interrogazioni ricorsive Il caso precedentemente visto corrisponde a un D aciclico in cui prima o poi l esecuzione è garantita terminare Inoltre non viene calcolata nessuna informazione aggiuntiva per i percorsi trovati Percorso: intuitivamente è la sequenza di tuple di cui si fa il join e che generano una tupla nel risultato finale (nell esempio visto corrisponde a una linea genealogica specifica) Vediamo nel seguito due casi notevoli Query ricorsive con informazione sui percorsi (lunghezza, costo, ecc.) Condizione di stop per query ricorsive su D ciclici SQL: viste Sistemi Informativi T 5 Informazione sui percorsi () Il caso più semplice prevede l aggiunta di un informazione sulla lunghezza (distanza, livello, ecc.) del percorso Nel caso già visto l output sarebbe: Genitori Figlio Genitore nna Luca Luca Maria Luca Giorgio Giorgio Lucia ntenati Persona vo nna Luca Luca Maria Luca Giorgio Giorgio Lucia nna Maria nna Giorgio Luca Lucia nna Lucia Lungh 3 SQL: viste Sistemi Informativi T 6 3
Informazione sui percorsi () La lunghezza parte da e si incrementa di a ogni passo, quindi: WITH ntenati(persona,vo,lungh) S ((SLCT Figlio,Genitore, -- caso base: Lungh = FROM Genitori) UNION LL (SLCT G.Figlio,.vo,.Lungh+ FROM Genitori G, ntenati WHR G.Genitore =.Persona)) SLCT * Persona vo Lungh FROM ntenati nna Luca WHR Persona = nna nna Maria nna Giorgio nna Lucia 3 SQL: viste Sistemi Informativi T 7 Informazione sui percorsi (3) In alcuni casi l informazione sui percorsi èun costo, oppure qualche altra grandezza cumulativa sempio: nella relazione PRTI, per ogni parte si dice quante unità di altre parti servono per costruirla/assemblarla SI vuole sapere quante unità di una parte servono complessivamente per costruire un altra parte Nell esempio: = *5 + 3*4 Parti Parte Subparte Qta Composto Componente QtaTot P P P P P P3 3 P P3 3 P 5 P 5 P3 4 P3 4 P SQL: viste Sistemi Informativi T 8 4
Informazione sui percorsi (4) In questi casi la soluzione prevede: l uso della ricorsione per calcolare l informazione di ogni singolo percorso P P : *5=0; P P3 : 3*4= l aggregazione delle informazione dei singoli percorsi nella query che usa la vista ricorsiva Parti Percorsi Parte Subparte Qta Composto Componente Qty P P P P P P3 3 P P3 3 P 5 P 5 P3 4 P3 4 P 0 P SQL: viste Sistemi Informativi T 9 Informazione sui percorsi (5) d ogni passo si moltiplica per quello che si aggiunge al percorso: WITH Percorsi(Composto,Componente,Qty) S ((SLCT Parte,Subparte,Qta FROM Parti) UNION LL (SLCT H.Composto,P.Subparte,H.Qty*P.Qta FROM Parti P, Percorsi H WHR H.Componente = P.Parte)) -- SLCT Composto,Componente,SUM(Qty) S QtaTot FROM Percorsi GROUP Y Composto,Componente SQL: viste Sistemi Informativi T 30 5
Database ciclici Nel caso di D ciclici occorre prestare particolare attenzione infatti necessario prevedere una condizione di stop, altrimenti il rischio èla non terminazione! Non facendo uso di altri strumenti non presentati nel corso, occorre inserire nella subquery ricorsiva un predicato che, prima o poi, sia falso per tutte le nuove tuple che si andrebbero ad aggiungere alla vista Casi tipici: limitazione sulla lunghezza massima dei percorsi limitazione sul costo SQL: viste Sistemi Informativi T 3 Limitazione sulla lunghezza dei percorsi () Il grafo in figura contiene un ciclo (percorso di lunghezza infinita): ------- Fissando un limite sulla lunghezza dei percorsi si generano solo percorsi di lunghezza finita, quindi l esecuzione prima o poi termina Per non perdere risultati, il limite va scelto in modo da non escludere percorsi interessanti Siti D C From C To D SQL: viste Sistemi Informativi T 3 6
Limitazione sulla lunghezza dei percorsi () Siti Percorsi Posto il limite ad es. a 3 si ha: WITH Percorsi(Da,,Lungh) S ((SLCT From,To, FROM Siti) UNION LL (SLCT P.Da,S.To,P.Lungh+ FROM Siti S, Percorsi P WHR P. = S.From ND P.Da <> S.To ND P.Lungh+ <= 3)) SLCT * FROM Percorsi D From C To D C Da C C D D D Lungh 3 SQL: viste Sistemi Informativi T 33 Limitazione sulla lunghezza dei percorsi (3) La condizione P.Da <> S.To serve ad evitare di inserire informazione inutile nel risultato enché in alcuni casi particolari possa essere usata anche come condizione di terminazione, nel caso generale non funziona! Percorsi Da Lungh Siti From To C C C C C C 3 C 4 5... SQL: viste Sistemi Informativi T 34 7
Limitazione sul costo In maniera simile si ragiona se si vuole imporre un limite al costo dei percorsi D Paesi WITH Percorsi(Da,,TotKm) From To Km S ((SLCT From,To,Km 7 4 5 FROM Paesi) C D 7 UNION LL 5 (SLCT P.Da,S.To,P.TotKm+S.Km C 4 FROM Paesi S, Percorsi P 0 WHR P. = S.From ND P.Da <> S.To Percorsi ND P.TotKm+S.Km <= 7)) Da Lungh SLCT * FROM Percorsi D In generale ci possono essere più percorsi tra 6 siti e va considerato quello a costo minore C 6 SQL: viste Sistemi Informativi T 7 35 Riassumiamo: Le viste sono tabelle virtuali, interrogabili come le altre, ma soggette a limiti per ciò che riguarda gli aggiornamenti Una table expression èuna subquery che definisce una tabella derivata utilizzabile nella clausola FROM Una common table expression è una vista temporanea che può essere usata in una query come se fosse a tutti gli effetti una VIW Mediante common table expression è anche possibile formulare interrogazioni ricorsive, definendo viste temporanee ricorsive come unione del risultato di una subquery base e una subquery ricorsiva SQL: viste Sistemi Informativi T 36 8