5. DDL - Vistes
5.1. Introducció
Suposem que tenim la taula: ALUMNES = codi + nom + edat + grup + domicili
Ja veiérem que a partir del resultat d'una SELECT podíem crear una taula:
Eixa instrucció crearà una nova taula amb les columnes especificades en la SELECT (codi, nom, grup i edat) i amb les files que complisquen la WHERE (menors d'edat). Ara bé: els canvis que es facen en la taula alumnes no implicaran canvis en la taula alumnes_menors ni viceversa:
- Si inserim un nou alumne de 15 anys en la taula
alumnes, eixe alumne no estarà en la taulaalumnes_menors(ni viceversa). - Si esborrem un alumne de
alumnes_menors, no s'esborrarà d'alumnes(ni viceversa). - Si en la taula d'alumnes modifiquem l'edat d'un alumne que abans era menor d'edat i fem que ara tinga 18 anys, l'alumne no desapareixerà de la taula
alumnes_menors. - ...
Volem solucionar això. És a dir: volem crear una taula especial a partir d'una altra, de forma que els canvis d'una es reflectisquen en l'altra. Realment, el que farem no serà copiar les dades d'una taula a una altra, sinó que crearem una "finestra" a partir de la qual vore les dades que volem de la taula. Això s'aconsegueix amb les vistes:
Així, amb la "finestra" (vista) anomenada alu_men, podrem vore el codi, nom, grup i edat dels alumnes de la taula alumnes que siguen menors de 18 anys. Per tant, si inserim un alumne nou de 1DAM en la taula alumnes, també el vorem des de la vista alu_men.
És a dir: si fem
... és com si férem:
Què és una vista?
Una vista és una taula virtual, ja que no té existència pròpia encara que exteriorment ho parega. És a dir, no existeix físicament (no ocupa espai en disc dur), sinó que és com una finestra a partir de la qual només podem vore una part (files i columnes) de les taules sobre les quals està definida.
5.2. Creació d'una vista
(comallista_nom_col): noms de les columnes que tindrà la vista. És opcional.
Tipus de la select de la vista
La select sobre la que es defineix la vista pot ser de qualsevol tipus: pot tindre columnes calculades (expressions), pot ser multitaula, pot tindre unions, group by, subconsultes...
També podem crear vistes a partir de selects sobre altres vistes.
Operacions que es poden fer sobre la vista
En principi, una vista és com una taula. Per tant, podrem fer sobre ella: select, insert, update, delete. Ara bé: cal tindre en compte que les sentències sobre la vista "es tradueixen" a sentències sobre la taula (o taules) sobre les quals està definida. Per tant, sempre podrem fer select sobre elles però no sempre un insert/delete/update sobre la vista es podrà traduir a un insert/delete/update sobre la taula (o taules) corresponent.
Per exemple, si una vista està definida amb un group by, si intentem fer un update sobre la vista, no hi haurà traducció per a fer update sobre la taula corresponent. Suposem la següent vista:
Podrem fer la següent sentència sobre la vista?
La resposta és no. En eixe cas es diu que la vista no és actualitzable.
Una vista és actualitzable si la select sobre la qual està definida no té "coses rares": no està creada amb UNION ni DISTINCT, ni GROUP BY, ni subconsultes, ni multitaula...
Clàusula WITH CHECK OPTION
Si en la definició d'una vista actualitzable s'inclou la clàusula WITH CHECK OPTION, esta no permetrà inserts o updates que no complisquen les condicions de la vista. Per exemple, si la vista alu_men l'haguérem creada amb esta clàusula, les següents instruccions donarien error:
| SQL | |
|---|---|
Destrucció d'una vista
| SQL | |
|---|---|
RESTRICT: no deixa esborrar la vista si hi ha altres vistes definides sobre ella.CASCADE: si hi ha altres vistes definides sobre ella, també les esborra.
MySQL accepta el RESTRICT i CASCADE, però passa d'ells. És a dir: deixa esborrar una vista V1 encara que hi haja alguna altra vista V2 definida a partir d'ella. Si férem una select sobre V2 donaria error. En altres SGBD, com PostgreSQL, sí que funciona.
5.3. Utilitats de les vistes
-
Permetre tindre en una taula informació derivada d'altres taules, de forma que les modificacions en eixes taules primitives també es reflectisquen en la "taula derivada" (vista).
-
Facilitar la construcció de selects complexes. Així podrem fer selects sobre altres "selects" ja fetes.
-
Permetre donar permisos sobre parts d'una taula (ja vorem el tema de permisos).
Exercicis. Vistes (BD lliga1213)
-
Crear una vista: a) Crea la vista
jug_sueamb el dorsal, nom i lloc dels jugadors de l'equip de codisue(no existeix en la taula de jugadors però dóna igual). No li poses la clàusula del check option. b) Comprova el contingut de la vistajug_sue. Caldrà fer un select sobre la vista. Voràs que no té res, ja que no hi ha jugadors d'eixe equip. -
Comprovació del funcionament de la vista: a) Inserix l'equip
tav(Tavernes C.F.) i elsue(Sueca United) en la taula d'equips. b) Inserix en la taula de jugadors dos nous davanters: Pep, del Tavernes C.F. i Pau, Sueca United. c) Comprova el contingut de la vistajug_sue. Voràs que ara la vista "sí que té" un jugador (Pau). Realment "no el té" però a través de la vista estem mirant els jugadors de la taula de jugadors que són del Sueca United. d) Fes que el jugador del Tavernes C.F. ara el fitxe el Sueca United (si cal, canviar-li també el dorsal). Caldrà fer un update. e) Torna a comprovar el contingut de la vistajug_sue. Ara estarem veient dos jugadors (Pau i Pep). f) Esborra a Pep de la taula jugadors. Cal fer delete sobre la taula. g) Esborra a Pau a través de la vistajug_sue. Cal fer delete sobre la vista. h) Comprova el contingut de la vistajug_sue. Ja no deu estar ningú dels dos. Comprova que tampoc estan en la taula jugadors. i) Intenta inserir a Pau a través de la vistajug_sue. Et donarà error perquè en l'insert no li posem el codi de l'equip i, per tant, quan s'intente inserir en la taula de jugadors no admetrà un null en el camp de l'equip. Però si no fóra per això, sí que es permet inserir a través d'una vista. -
Eliminar una vista: a) Elimina la vista anterior (
jug_sue). No que esborres els seus registres, sinó que la destruïsques. Caldrà fer un drop de la vista. Això no afecta a la taula sobre la qual estava definida. -
Crear una vista amb el check option: a) Crea la vista
equipetsamb el codi, nomcurt i pressupost de tots els equips que tinguen un pressupost inferior a 30 milions d'euros. Fes-ho amb el check option. b) Insereix a través de la vistaequipetsestos equips, en 2 inserts: - Equipgan, "C.F. Gandia", amb 0 milions d'euros de pressupost. - Equipand, "Andorra C.F", amb 31 milions d'euros de pressupost. Ha de donar error per no complir la condició del check option. c) Esborra a través de la vistaequipetsels equips de més de 40 m. de pressupost. No donarà error però no esborrarà cap equip, degut al check option. d) A través de la vistaequipetsfes que el nou pressupost del C.F. Gandia ara siga de 31 m. Donarà error per no complir el check option. -
Crear una vista no actualitzable: a) Crea la vista
equips_nombrososamb el codi de l'equip, el nom curt, el nom de la ciutat i la quantitat de jugadors de cadascun. Però només amb aquells equips que tinguen més de 30 jugadors en plantilla. Els noms de les columnes seran:codi,nom,ciutat,plantilla. b) En la vistaequips_nombrososmodifica el nom de l'equip del Betis (codibet): ara es dirà "Betis". Donarà un error dient que la vista no és actualitzable. No ho és perquè com té group by (i multitaula), no es pot "traduir" eixe update sobre la vista a un update sobre taules. El mateix passaria si intentem fer inserts o deletes sobre eixa vista. -
Crear una vista a partir d'altra (exercici solucionat): a) Crea la vista
resultats_equipsamb estos camps: -equip: codi de l'equip -pgc: quantitat de Partits Guanyats a Casa -pec: quantitat de Partits Empatats a Casa -ppc: quantitat de Partits Perduts a Casa -pgf: quantitat de Partits Guanyats Fora -pef: quantitat de Partits Empatats Fora -ppf: quantitat de Partits Perduts ForaEste tipus de consulta es fa amb subconsultes dins de la pròpia clàusula select. No et preocupes si no t'ix. Estes consultes només s'han vist en algun exercici. La solució seria esta:
b) Crea la vista
classifamb els camps següents. Crea-la a partir de la vistaresultats_equips: -equip= Codi de l'equip -pjc= Partits Jugats a Casa -pgc= Partits Guanyats a Casa -pec= Partits Empatats a Casa -ppc= Partits Perduts a Casa -puntsc= Punts a Casa -pjf= Partits Jugats Fora -pgf= Partits Guanyats Fora -pef= Partits Empatats Fora -ppf= Partits Perduts Fora -puntsf= Punts Fora -pjt= Partits Jugats en Total -pgt= Partits Guanyats en Total -pet= Partits Empatats en Total -ppt= Partits Perduts en Total -puntst= Punts en TotalLa solució seria:
c) Crea la vista
classif2amb els camps declassifmés altres camps calculats: gols marcats (a casa, fora i en total), rebuts (a casa, fora i en total) i els que vulgues.d) Consultes sobre les vistes. Les vistes que hem fet ens serviran per a fer més fàcils consultes com les següents:
d.1) Mostra la taula classificatòria (vista
classif) ordenada pels punts totals descendents. També ha d'eixir (en la primera columna) el nom llarg de l'equip.SQL d.2) Equips que han aconseguit més del doble de punts a casa que fora de casa. Mostra també els punts totals a casa, els punts totals fora i els punts totals. Decreixent pels punts a casa.
SQL d.3) Mostra els punts que tenen els equips de la ciutat amb més habitants i de la ciutat amb menys habitants. Mostra també el nom de la ciutat, el nom curt de l'equip i els habitants de la ciutat.