Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

Viste (InterBase e Firebird)

Alexey Kovyazin, ultimo aggiornamento 13-aprile-2012

Coloro che hanno familiarità con il linguaggio SQL non richiedono spiegazioni dettagliate su questo argomento, ma per preservare la sequenza di presentazione, introdurremo una breve definizione di viste.

Una VISTA è una tabella virtuale creata sulla base di una query su tabelle ordinarie. Una vista è implementata come query, memorizzata sul server ed eseguita ogni volta che ci si riferisce a una vista.

Consideriamo diverse varianti di utilizzo delle viste. Le viste consentono di creare livelli di struttura dei dati, permettendo di separare l’implementazione dell’archiviazione dei dati dal loro tipo. Ad esempio, possiamo creare una vista che seleziona i dati da più tabelle. Se i clienti utilizzano questa vista invece di riferirsi direttamente alle tabelle sottostanti, lo sviluppatore del database sarà in grado di modificare la query alla base della vista, di alterarla (per ottimizzarla, ad esempio), e il cliente non noterà nulla - sarà la stessa vista per lui. Oltre al fatto che isolano l’implementazione dell’archiviazione dei dati dall’utente, le viste consentono di organizzare i dati in modo più comodo e semplice. Il problema della “semplificazione” della struttura dei dati sorge quando il numero di tabelle in un database diventa abbastanza grande e le interrelazioni tra loro - complicate. La vista consente di eliminare (o, al contrario, di aggiungere) una parte dei dati non necessari al concreto cliente del database (o - necessari).

Inoltre, le viste consentono di organizzare la sicurezza nel database InterBase in modo più semplice. Alcuni utenti possono avere diritti solo di lettura/aggiornamento dei dati nella vista, ma non avere diritti (e nemmeno idea) sulle tabelle sottostanti la vista! Per maggiori dettagli sulla sicurezza in InterBase, vedere il capitolo “Sicurezza in InterBase: utenti, loro funzioni e diritti” (parte 4).

Sintassi DDL per lavorare con le viste

Ora considereremo i comandi per creare ed eliminare viste definiti da DDL (Data Definition Language - sottoinsieme di SQL, vedere il glossario). Per creare una vista in InterBase, dobbiamo usare la frase con la seguente sintassi:

CREATE VIEW nomevista [(colonna_vista[, colonna_vista…])] AS [WITH CHECK OPTION]; Qui nomevista è il nome della vista che deve essere unico all’interno di un database, e poi segue un gruppo di nomi non sempre obbligatori dei campi inclusi nella vista: [(colonna_vista [, colonna_vista …])]. È essenziale definire l’istruzione che seleziona i dati inclusi nella vista. Discuteremo il parametro opzionale WITH CHECK OPTION un po’ più avanti nella parte “Viste modificate”.

Per modificare la vista, dovremo ricrearla, cioè eliminarla e crearla di nuovo. Quando si elimina la vista, è necessario eliminare anche tutti gli oggetti dipendenti - i trigger, le procedure memorizzate e altre viste. Questo è uno dei principali inconvenienti del lavoro con le viste: la necessità di ricreare l’albero di oggetti che utilizzano la vista (esistono utility che ci consentono di farlo più facilmente, ad esempio IBAlterView, vedere l’applicazione “Strumenti per amministratore e progettista InterBase”). Dovremmo usare il seguente comando DDL se vogliamo eliminare la vista:

DROP VIEW nomevista;

Esempi di viste

Ecco un esempio di vista semplice:

CREATE VIEW MyView AS SELECT NAME, PRICE_1 FROM Table_example;

In questo esempio, creiamo una vista basata su una query alla tabella Table_example che abbiamo considerato nel capitolo “Tabelle. Chiavi primarie e generatori”. In questo caso, la vista sarà composta da due campi - NAME e PRICE_1, che saranno selezionati dalla tabella Table_example senza alcuna condizione, cioè il numero di record nella vista MyView sarà uguale al numero di record in Table_example. Tuttavia, le viste non sono sempre così semplici. Possono essere basate sui dati di più tabelle e persino su altre viste. Inoltre, le viste possono contenere dati ricevuti sulla base di diverse espressioni - inclusa la base di funzioni aggregate. Per considerare l’utilizzo di questa applicazione di vista in modo più dettagliato, creiamo due tabelle unite da una relazione uno-a-molti (spesso tale relazione è chiamata master-detail). Ecco lo script DDL per creare queste tabelle:

/\* Tabella: WISEMEN */

CREATE TABLE WISEMEN ( ID_WISEMAN INTEGER NOT NULL, WISEMAN_NAME VARCHAR(80));

/\* Definizione delle chiavi primarie */

ALTER TABLE WISEMEN ADD CONSTRAINT PK_WISEMEN PRIMARY KEY (ID_WISEMAN);

/\* Tabella: WISEBOOK */

CREATE TABLE WISEBOOK ( ID_BOOK INTEGER NOT NULL, ID_WISEMAN INTEGER, BOOK VARCHAR(80));

/\* Definizione delle chiavi primarie */

ALTER TABLE WISEBOOK ADD CONSTRAINT PK_WISEBOOK PRIMARY KEY (ID_BOOK);

/\* Definizione delle chiavi esterne */

ALTER TABLE WISEBOOK ADD CONSTRAINT FK_WISEBOOK FOREIGN KEY (ID_WISEMAN) REFERENCES WISEMEN (ID_WISEMAN);

Quindi, abbiamo creato due tabelle - WISEMEN e WISEBOOK unite da una relazione master-detail utilizzando un vincolo di chiave esterna - FOREIGN KEY. Supponiamo che queste tabelle memorizzeranno le informazioni sui grandi saggi cinesi e le loro opere. Ora possiamo creare alcune viste basate su queste tabelle. Ad esempio, creiamo la vista che mostra quante opere ha ciascun saggio:

CREATE VIEW WiseBookCount (WISEMAN, HOW_WISEBOOKS) AS SELECT M.WISEMAN_NAME, COUNT(B.BOOK) FROM WISEMEN M, WISEBOOK B WHERE (M.ID_WISEMAN = B.ID_WISEMAN) GROUP BY M.WISEMAN_NAME

Prestare attenzione che quando si utilizzano espressioni calcolate come funzioni aggregate COUNT (), SUM (), MAX (), ecc., è essenziale usare nomi definiti dei campi della vista, cioè dare nomi a tutti i campi restituiti dalla query. Come possiamo vedere da questo esempio, questi nomi non devono necessariamente coincidere con i nomi dei campi della query, ma la loro quantità deve coincidere con la quantità di campi restituiti dalla query. La definizione di quale campo restituito dalla query corrisponde a quale campo della vista è fatta tramite numero di serie - il primo campo della query sarà riflesso nel primo campo della vista, il secondo - nel secondo, ecc.

E se volessimo sapere quale dei saggi ha scritto più libri? Proveremo ad aggiungere l’espressione per l’ordinamento - ORDER BY alla query alla base della vista. Tuttavia, questo tentativo non avrà successo: l’uso dell’ordinamento ORDER BY nelle viste non è consentito e quando si tenta di creare la vista con la query contenente ORDER BY, si verificherà un errore. Se vogliamo ordinare i risultati restituiti dalla vista, dovremo farlo per conto del cliente:

SELECT * FROM WiseBookCount ORDER BY HOW_WISEBOOKS

L’esecuzione di questa query SQL porterà a un risultato desiderabile. Oltre al vincolo per l’uso dell’espressione ORDER BY nelle viste, non possiamo nemmeno utilizzare il set di dati ricevuto come risultato dell’esecuzione di procedure memorizzate come fonte di dati (vedere il capitolo “Procedure memorizzate” più avanti).

Forse, vale la pena fare un altro esempio che illustra l’applicazione delle viste. Supponiamo di dover emettere un elenco di saggi il cui nome inizia con la lettera “K”. In questo caso, useremo la vista con condizioni:

CREATE VIEW WiseMen2 (WISEMAN) AS SELECT M.WISEMAN_NAME FROM WISEMEN M WHERE M.WISEMAN_NAME LIKE ‘K%’

Quindi, è facile creare viste che svolgono il ruolo di fornitori di dati costantemente aggiornabili, selezionandoli da un database secondo condizioni definite.

Viste modificate

Abbiamo menzionato sopra che esiste la capacità di creare viste di dati modificate. È davvero così - esiste la capacità non solo di leggere i dati dalla vista, ma anche di modificarli!

Ci sono due modi per rendere la vista modificata. Il primo modo è applicato quando la vista è creata sulla base di una tabella unica (o altra vista modificata), e tutte le colonne della tabella data devono consentire la presenza di NULL. Quindi la query su cui si basa la vista non può contenere subquery, funzioni aggregate, UDF, procedure memorizzate, istruzioni DISTINCT e HAVING. Se tutte queste condizioni sono soddisfatte, la vista diventa automaticamente modificata, cioè possiamo eseguire le query DELETE, INSERT e UPDATE su di essa, che altereranno i dati nella tabella sorgente.

L’elenco delle condizioni è piuttosto impressionante e limita notevolmente l’applicazione di tali viste modificate, di conseguenza sono usate abbastanza raramente.

Per rendere modificata una vista che viola una qualsiasi delle condizioni sopra elencate, viene applicato il meccanismo dei trigger. Per maggiori dettagli sui trigger, vedere il capitolo “Trigger” (parte 1). Ora considereremo solo i principi generali dell’organizzazione dell’alterazione dei dati in VIEW.

Per l’implementazione di una vista aggiornata utilizzando i trigger, si deve fare quanto segue. Creare 3 trigger per la vista data per gli eventi: BEFORE DELETE, BEFORE UPDATE e BEFORE INSERT. Descrivere in questi trigger cosa dovrebbe essere fatto con i dati quando si eliminano, aggiornano e inseriscono.

Poi dovremmo usare la vista data in query di modifica - DELETE, INSERT o UPDATE. Quando InterBase riceverà questa query, controllerà se ci sono trigger appropriati per la vista data, cioè BEFORE DELETE/INSERT/UPDATE. Se il trigger per l’azione eseguibile esiste, InterBase lo chiamerà per la modifica dei dati reali nelle tabelle sottostanti la vista (anche se potrebbero essere altri dati - non ci sono vincoli testuali di questi trigger), e poi rileggerà la stringa (o le stringhe) su cui è stata eseguita la modifica.

Quindi, c’è la capacità di realizzare complesse catene di aggiornamento dei dati nelle viste.

L’opzione WITH CHECK OPTION è stata menzionata nella descrizione della sintassi di creazione della vista. Se questa opzione è impostata quando si crea una vista modificata, ogni stringa di dati inserita o alterata in questa vista sarà controllata su una condizione di appartenenza alla vista. Può essere spiegato così: se un nuovo record inserito dall’utente o ricevuto come risultato dell’aggiornamento del record esistente non soddisfa le condizioni della query, che è il fornitore di dati per VIEW, l’inserimento di questo record sarà annullato e si verificherà un errore.

Conclusione

Nonostante l’apparente semplicità di creazione e utilizzo delle viste, esse forniscono grandi capacità per migliorare l’organizzazione dei dati in un database e consentono di creare una gerarchia di organizzazione dei dati.

Alcuni progettisti di applicazioni di database usano le viste molto spesso nel loro lavoro, altri evitano la loro applicazione, motivandola con una complessità di modifica delle viste e la tendenza a preservare lo schema del database il più semplice ed efficace possibile. Sta a voi come applicherete le viste nel vostro lavoro. Il punto più importante è ricordare l’esistenza di uno strumento così potente come la vista, e sapere come usarlo.