SQL: Lezione 7 Nataliya Rassadko [email protected].
-
Upload
emanuele-nanni -
Category
Documents
-
view
227 -
download
2
Transcript of SQL: Lezione 7 Nataliya Rassadko [email protected].
SQL: Lezione 7
Nataliya [email protected]
Agenda
User-defined dominiDEFAULTVincoli intra-relazionali
NOT NULL, UNIQUE, PRIMARY KEY Vincoli sui valori delle tuple
Vincoli inter-relazionali Integrità referenziale
Vincoli genericiModifica degli schemi
ALTER, DROPViste, Indici, Asserzioni
DEFINIZIONE DEI DOMINI
Nella definizione delle tabelle si può far riferimento ai domini predefiniti del linguaggio o a domini definiti dall’utente a partire dai domini predefiniti.
Definiscono i valori accetabili
Come nei linguaggi ad alto livello (es. C) è possibile definire nuovi domini (tipi di dati) a partire da quelli predefiniti, anche se il costruttore è più limitato.
DEFINIZIONE DEI DOMINI
Non si possono creare array o strutture poiché il modello relazionale impone attributi definiti su un dominio elementare.
E’ però possibile associare dei vincoli ad un dominio definito dall’utente. Se si modifica la definizione di un dominio, la modifica si propaga a tutte le tabelle.
DEFINIZIONE DEI DOMINI
La sintassi per la creazione di nuovi domini è la seguente:
CREATE DOMAIN NomeDominio AS TipoDiDominioElementare [ValorePredefinito] [Vincoli]
DEFINIZIONE DEI DOMINI
Un dominio è caratterizzato: dal proprio nome, da un dominio elementare (che può essere
predefinito o definito in precedenza dall’utente), da un eventuale valore di default, e infine da un insieme di vincoli (eventualmente vuoto)
che rappresenta un insieme di condizioni che devono rispettare i valori del dominio
ESERCIZIO
Creare un dominio che permetta di assegnare ad un attributo un valore intero, non nullo, compreso tra 18 e 30
Altri domini
CREATE DOMAIN Voto AS SMALLINT
NOT NULL
CHECK ( value >=18 AND value <= 30 )
CREATE DOMAIN NumberOfChildren AS SMALLINT Default 0
CREATE DOMAIN persons_name CHAR(30)
CREATE DOMAIN street_address CHAR(35)
VALORI PREDEFINITI
Specifica il valore che deve assumere l’attributo quando viene inserita una riga nella tabella senza che sia specificato un valore per l’attributo stesso
Quando il valore di default non è specificato, si assume come default il valore Null.
La sintassi per la specifica dei valori di default è:
default (GenericoValore | user| null)
VALORI DEFAULT
GenericoValore rappresenta un valore compatibile con il dominio, rappresentato direttamente come valore costante o, più in generale, ottenuto come risultato della valutazione di un espressione.
L’opzione user impone come valore di default l’identificativo dell’utente (login) che esegue il comando di aggiornamento della tabella.
L’opzione null corrisponde al valore di default di base.
VINCOLI
Sia nella definizione di domini che nella definizione delle tabelle è possibile definire dei vicoli.
Delle proprietà che devono essere verificate da ogni istanza della base di dati.
I vincoli si dividono in due categorie: vincoli intrarelazionali (che coinvolgono una sola tabella) e vincoli interrelazionali (in cui il predicato considera diverse relazioni)
VINCOLI INTRARELAZIONALI
I più semplici vincoli di tipo intrarelazionale sono i vincoli
NOT NULL,Unique,Primary Key.
NOT NULL
Il vincolo NOT NULL indica che il valore nullo non è ammesso come valore per quel specifico attributo.
Quando viene assegnato questo vincolo, l’attributo deve essere sempre specificato, tipicamente in fase di inserimento.
Se all’attributo è però associato un valore di default diverso dal valore nullo, allora diventa possibile effettuare l’inserimento di una riga per la tabella senza fornire un valore per l’attributo.
NOT NULL: Esempio
Il vincolo viene specificato facendo seguire alla definizione dell’attributo le parole chiave NOT NULL:
MovieTitle VARCHAR(50) NOT NULL;
UNIQUE
Un vincolo UNIQUE si applica ad un attributo o un insieme di attributi.
Impone che i valore dell’attributo siano una (super)chiave: cioè righe differenti della tabella non possano avere gli stesi valori.
Viene fatta un’eccezione per il valore NULL , il quale può comparire su diverse righe senza violare il vincolo.
Si assume che i valori NULL siano tutti i diversi tra loro.
UNIQUE
La definizione di questo vincolo può avvenire in due modi
La prima alternativa può essere usata unicamente quando bisogna definire il vincolo su un solo attributo.
Si fa seguire la specifica dell’attributo dalla parola chiave unique:StudioName VARCHAR(50) NOT NULL UNIQUE;
UNIQUE
La seconda alternativa è invece necessaria quando bisogna definire il vincolo per un insieme di attributi.
Dopo aver definito gli attributi della tabella, si usa la seguente espressione
Un esempio d’uso della sintassi è il seguente:
Unique (Attributo {,Attributo})
Nome character(20) not null
Cognome character(20) not null
Unique (Cognome,Nome)
UNIQUE
Si noti che la precedente definizine è ben diversa da una definizione come:
Nel primo caso si impone che non ci siano due righe che abbiano uguali sia il nome che il cognome, nel secondo si ha una violazione se nelle righe compaiono due volte lo stesso nome o lo stesso cognome.
Nome character(20) not null Unique
Cognome character(20) not null Unique
PRIMARY KEY
SQL permette di specificare il vincolo primary key una sola volta per ogni tabella.
E’ possibile utilizzare un numero arbitrario di volte i vincoli unique e not null.
Come per il vincolo unique, il vincolo primary key può essere definito direttamente su di un singolo attributo, oppure essere definito elencando più attributi che costituiscono l’identificatore.
PRIMARY KEY
Gli attributi che fanno parte della chiave primaria non possono assumere il valore nullo.
La definizione di una primary key implica per tutti gli attributi della chiave primaria una definizione di not null, che può quindi essere omessa.
PRIMARY KEY
La definizione impone che la coppia di attributi Nome e Cognome costituiscano la chiave primaria.
Nome character(20)
Cognome character(20)
Dipart character(16)
Stipendio numeric(9) default 0,
Primary Key (Cognome,Nome)
VINCOLI INTRARELAZIONALI Cont’d
Un vincolo è intrarelazionale se il suo soddisfacimento è definito rispetto singole relazioni della base di dati.
È un vincolo che può essere valutato su ciascuna tupla indipendententemente dalle altre.
Esistono due categorie principali: Vincoli di tupla Vincoli di valore
VINCOLI DI VALORE
Un vincolo definito con riferimento a singoli valori viene detto vincolo su valori o vincolo di dominio in quanto impone una restrizione sul dominio dell'attributo.
Un esempio è il vincolo not null, usato per dichiarare che un dato attributo non può assumere il valore nullo. Solitamente questo attributo viene corredato da un valore di default, che viene assegnato automaticamente all'atto della creazione di una nuova tupla
VINCOLI DI VALORE e TUPLA
Il primo vincolo (vincolo di valore in quanto coinvolge un solo attributo) indica che l’attributo VOTO può assumere solo valori compresi tra 18 e 20.
Il secondo vincolo indica che è amissibile la lode solo se il voto è pari a 30.
(Voto >= 18) AND (Voto <= 30)
(NOT (Lode = ‘lode’) AND (Voto = 30)
VINCOLI DI TUPLA
I vincoli di tupla ammettono anche espressioni piu complesse, purchè definite sui valori delle singole tuple.
Ad esempio, su una relazione
E’ possibile definire il vincolo che impone, che il netto sia pari alla differenza fra l’importo originario e le ritenute
PAGAMENTI(Data,Importo,Ritenute,Netto)
Netto=Import-Ritenute
ESERCIZIO
Ricreare, all’interno dello schema work, le tabelle presenti all’interno dello scema imdb, fissando i vincoli necessari.(Cancellare e ricreare la tabella Movie (nel db di prova) appena creata: Per cancellare una tabella DROP nome_tabella)
VINCOLI INTERRELAZIONALI
I più diffusi e significativi sono i vincoli di INTEGRITA’ REFERENZIALE.
In SQL per la loro definizione si usa l’apposito vincolo di FOREIGN KEY (chiave esterna)
Crea un legame tra i valori di un attributo della tabella corrente (interna) e i valori di un altra tabella (esterna)
INTEGRITA’ REFERENZIALE
Il vincolo impone che per ogni riga della tabella il valore dell’attributo specificato, se diverso dal valore nullo, sia presente nelle righe della tabella esterna tra i valori del corrispondente attributo
MovieExec Studio
name address cert#
Kubrick 45 ave. 3565
… … …
name presC#
Paramount Pictures 3565
… …
MovieExec Studio
INTEGRITA’ REFERENZIALE
ESEMPIO:E’ possibile forzare il db a controllare che per ogni valore di presC# nella relazione Studio, ci sia una righa con lo stesso valore per l’attributo cert# nella relazione MovieExec
Il Db blocchera’ tutti i tentativi di inserimento di una riga in Studio con un presidente “unknown”
INTEGRITA’ REFERENZIALE
In SQL e’ possibile dichiarare un attributo (o piu’) di una relazione (R1) come una foreign key, riferendosi agli attributi di una altra relazione (R2), cosi’ che:
L’attributo di R2 riferito deve essere dichiarato come UNIQUE o come PRIMARY KEY.
I valori per la chave esterna che appaiono in R1 devono apparire anche negli attributi di riferimento nella tabella R2
INTEGRITA’ REFERENZIALE
In modo simile al caso delle Primary Keys, le Foreign Keys possono essere definite nell’istruzione CREATE TABLE in uno dei seguenti modi:
CREATE TABLE nome_table {attributo1 attributo2 attributoN REFERENCES “Tabella Esterna“ (“attributo") }
CREATE TABLE nome_table {attributo1 attributo2 attributoN foreign key (attributo1, attributo2) REFERENCES “Tabella Esterna“ (lista attributi)}
INTEGRITA’ REFERENZIALE
Per gli altri vincoli visti fino ad ora, si assume che quando il sistema rileva una violazione, il comando di aggiornamento venga rifiutato, segnalando l’errore all’utente.
Per i vincoli di integrità referenziale invece è possibile scegliere le azioni da adottare quando viene rilevata una violazione.
INTEGRITA’ REFERENZIALE
In particolare, per le operazioni di modifica, è possibile reagire in uno dei seguenti modi: Cascade: il nuovo valore dell’attributo della tabella esterna
viene riportato su tutte le corrispondenti righe della tabella interna
Set null: all’attributo referente viene assegnato il valore nullo al posto del valore modificato nella tabella esterna.
Set default: all’attributo referente viene assegnato il valore di default al posto del valore modificato nella tabella esterna
No action: l’azione di modifica non viene consentita, senza che il sistema provi a riparare la violazione.
INTEGRITA’ REFERENZIALE
In particolare, per le operazioni di cancellazione, è possibile reagiere in uno dei seguenti modi: Cascade: tutte le righe della tabella interna corrispondenti
alla riga cancellata vengono cancellate. Set null: all’attributo referente viene assegnato il valore
nullo al posto del valore cancellato nella tabella esterna. Set default: all’attributo referente viene assegnato il
valore di default al posto del valore cancellato nella tabella esterna.
No action: la cancellazione non viene consentita.
INTEGRITA’ REFERENZIALE
Le politiche possono essere definite , in maniera indipendente per cancellazione e modifica
Le politiche da adottare sono definite durante la dichiarazione della chiave esterna sulla cancellazione o sull‘aggiornamento. CREATE TABLE "Studio"
( "name" CHAR(30) PRIMARY KEY, "address" VARCHAR(255), "presC#" INT REFERENCES "MovieExec"("cert#") ON DELETE SET NULL ON UPDATE CASCADE );
VINCOLI GENERICI
• La clausola check permette di specificare dei nuovi vincoli sulle tabelle rispetto a quelli fino ad ora visti.
Le condizioni che si possono essere applicate con il vincolo CHECK sono le stesse che possono apparire come clausola where di un interrogazione SQL.
Check (Condizione)
CHECK
La condizione deve essere sempre verificata affinchè la base di dati sia corretta.
E’ possibile definire un vincolo sul valore di un attributo specificando una numerazione legale, una condizione aritmetica o una subquery.
"netWorth" INT CHECK ("netWorth">=100000)
CHECK
E’ possibile definire un vincolo sulla riga :
Ogni volta che una riga e’ inserita o modifcata, viene controllato che il vincolo sia rispettato dalla nuova riga inserita.
Se il vincolo non e’ rispettato l’inserimento viene rifiutato.
CREATE TABLE “nameTable"( “att1" tipo vincolo, “att2” tipo vincolo,
…
CHECK (condizione sulla riga));
ESERCIZIO
Ridefinire lo schema MovieStar imponendo che il nome dell’attore non abbia il prefisso Ms. se il sesso è diverso da ‘F’.
CREATE TABLE "MovieStar"( "name" CHAR(30) PRIMARY KEY, "address" VARCHAR(255), "gender" char(1), "birthday" DATE, CHECK ("gender"='F' OR "name" NOT LIKE 'Ms.%'));
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
Ridefinire lo schema Movie imponendo che l’attributo inColor non possa valere ‘true’ se l’anno di produzione del film è minore di 1940.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#)
CREATE TABLE "Movie"( “title” VARCHAR(255) PRIMARY KEY, “year” INT PRIMARY KEY, …
…
CHECK (“year"<‘1940' OR “inCOLOR" NOT LIKE ‘true'));
VINCOLI
E’ possibile definire un nome per i vincoli
E’ possibile aggiungere dei vincoli ad uno schema gia definito
"name" CHAR(30) CONSTRAINT "NameIsKey" PRIMARY KEY
CONSTRAINT "RightTitle" CHECK ("gender"='F' OR "name" NOT LIKE 'Ms.%'));
ALTER TABLE imdb."MovieStar" ADD CONSTRAINT "NameIsKey" PRIMARY KEY("name");
MODIFICA DEGLI SCHEMI
SQL fornisce primitive per la manipolazione degli schemi delle basi di dati.
Queste primitive permettono di modificare le definizioni di tabelle precedentemente introdotte.
I comandi che vengono utilizzati a questo fine sono ALTER e DROP
ALTER
Il comando ALTER permette di modificare domini e schemi di tabelle.
Il comando può assumere varie forme:
Alter domain NomeDominio (set default ValoreDefault| drop default | add constraint DefVincolo | drop constraint NomeVincolo)
ALTER
Alter table NomeTabella( alter column NomeAttributo ( set default ValoreDefault | drop default) | add constraint DefVincolo | drop constraint NomeVincolo | add column DefVincolo | drop column NomeVincolo)
ALTER: Esempio
ALTER TABLE MovieStar ADD COLUMN phone CHAR(16);
ALTER
Tramite alter domain e alter table è possibile aggiungere e rimuovere vincoli e modificare i valori di default.
È possibile aggiungere e eliminare attributi e vincoli sullo schema di una tabella.
Quando si definisce un nuovo vincolo, questo deve essere soddisfatto dai dati già presenti, se l’istanza contiene delle violazioni per il nuovo vincolo l’inserimento viene rifiutato.
ALTER: Esempio
ALTER TABLE MovieStar ADD CONSTRAINT NameIsKey PRIMARY KEY (name);
ALTER TABLE MovieStar ADD CONSTRAINT NoAndro CHECK (gender IN (‘M’, ‘F’));
ALTER TABLE MovieStar ADD CONSTRAINT RightTitle CHECK (gender=‘F’ OR name NOT LIKE ‘MS.%’);
DROP
Mentre il comando alter effettua delle modifiche sui domini o sullo schema delle tabelle.
Il comando drop permette di rimuovere dei componenti, siano essi schemi, domini, tabelle, viste o asserzioni.
Drop (schema|domain|table|view|assertion) NomeElemento [restrict|cascade]
DROP
L’opzione restrict spefica che il comando non deve essere eseguito in presenza di oggetti non vuoti: uno schema non è rimosso se contiene tabelle o altri
oggetti Una tabella non è rimossa se possiede delle righe o se
è presente in qualche definizione di tabella o vista. Una vista non è rimossa se è utilizzata nella
definizione di altre viste o tabelle.
DROP
Con l’opzione cascade invece, tutti gli oggetti specificati devono essere rimossi.
Quando si rimuove uno schema non vuoto, anche tutti gli oggetti che fanno parte dello schema vengono eliminati.
In generale, l’opzione cascade attiva una reazione a catena, per cui tutti gli elementi che dipendono da un elemento rimosso vengono rimossi
DROP: Esempio
ALTER TABLE MovieStar DROP COLUMN birthdate;
ALTER TABLE MovieStar DROP CONSTRAINT NameIsKey;
ALTER TABLE MovieStar DROP CONSTRAINT NoAndro;
ALTER TABLE MovieStar DROP CONSTRAINT RightTitle;
VISTE
Sono tabelle virtuali il cui contenuto dipende dal contenuto delle altre tabelle presenti nel db.
Esistono anche le viste materializzateLe viste vengono definite associando un nome
ed una lista di attributi al risultato dell’esecuzione di una interrogazione.
Nell’interrogazione che definisce la vista possono comparire anche altre viste
VISTE
La sintassi SQL non permette dipendenze ricorsive, né immediate: definendo una vista in termini di se stessa.
né transitive: situazioni in cui una vista V1 è definita usando un vista V2, V2 usando V3 e cosi via, infine Vn usando V1.
VISTE
Si definisce una vista utilizzando il comando:
L’interrogazione SQL deve restituire un insieme di attributi pari a quelli contenuti nello schema
L’ordine nella target list deve corrispondere all’ordine degli attributi dello schema della vista.
Create view NomeVista [(ListaAttributi)] as SelectSQL [with[local|cascaded]check option]
ESERCIZIO
Definire una vista EXECREACH che contenga tutti i produttori con un networth superiore a 10 milioni.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#)
Create view EXECREACH (name,address,cert#,netWorth) as Select name,address,cert#,netWorth from MovieExec where netWort>’10.000.000’
ESERCIZIO
Definire una vista MovieOld in cui sono contenuti tutti i film in bianco e nero prodotti prima del 1950Movie(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 view ParamauntMovie as
Select title,year
from Movie
where studioName=‘Paramaount’
VISTE VIRTUALI
Possiamo creare SELECT su viste
i query saranno rescritte
Create view ParamauntMovie as
Select title,year
from Movie
where studioName=‘Paramount’
SELECT title FROM ParamountMovie WHERE year=1979
SELECT title FROM ParamountMovie WHERE year=1979
AND studioName=‘Paramount’
VISTE
Su alcune viste è permesso effettuare operazioni di modifica
Le modifiche verranno tradotte negli opportuni comandi di modifica a livello delle tabellle di base da cui la vista dipende.
Non è sempre possibile determinare un modo univoco in cui la modifica sulla vista possa essere riportata sulle tabelle di base
VISTE
Si incontrano grossi problemi soprattutto quando la vista è definita tramite una join tra più tabelle.
Lo standard SQL permette che una vista sia aggiornabile solo quando una sola riga di ciascuna tabella di base corrisponde a una riga della vista.
I sistemi commerciali tipicamente considerano una vista aggiornabile solo se è definita su una sola tabella.
VISTE: Esempio di inserimento
Create view ParamauntMovie as Select title,year
from Movie where studioName=‘Paramount’
INSERT INTO ParamountMovie VALUES (‘Star Treck’, 1979)
Movie(title,year,length,inColor,studioName,producerC#)
‘Star Treck’, 1979, 0, NULL, ?, NULL
Create view ParamauntMovie as
Select studioName, title,year
from Movie where studioName=‘Paramount’
VISTE
Le viste in SQL possono servire per formulare delle interrogazioni che non sarebbero altrimenti esprimibili, aumentando il potere espressivo del linguaggio.
Mediante la definizione di opportune viste, è possibile definire in SQL interrogazioni che richiedono: di utilizzare diversi operatori aggregati in cascata. Che fanno un uso sofisticato dell’operatore unione.
In generale, le viste possono essere considerate come uno strumento che permette di estendere la possibilità di nidificare le interrogazioni.
ESERCIZIO
Data la tabella IMPIEGATO, determinare il dipartimento che spende la cifra massima in stipendi (utilizzando le viste)
Impiegato(matricola,nome,cognome,dipart,ufficio,stipendio,citta)
create view BudgetStipendi(dipart,totaleStipendi) as Select dipart, sum(stipendio) from Impiegato
group by dipart
Select Dip from BudgetStipendi where TotaleStipendi= (Select max(TotaleStipendi) from BugdgetStipendi)
ESERCIZIO
Formulare l’interrogazione precedente senza l’uso delle viste.Impiegato(matricola,nome,cognome,dipart,ufficio,stipendio,citta)
Select Dipart from Impiegato group by Dipart having sum(Stipendio) >= all(select sum(Stipendio) from Impiegato group by Dipart)
ESERCIZIO
Scrivere una vista che restituisca il numero di uffici per ciascun dipartimento
In questo caso, la vista può servire per restrizione dell’accesso ai dati
Create view DipartUffici(nomeDip,nrUffici) as Select dipart, count(distinct ufficio) from Impiegato
group by dipart
Impiegato(matricola,nome,cognome,dipart,ufficio,stipendio,citta)
INDICI
Gli indici permettono ad un DBMS di accedere ai dati più rapidamente.
Il sistema crea della strutture dati interne (gli indici) per la selezione veloce di determinate righe.
La struttura indica al DBMS dove si trova una certa riga su una tabella con colonne indicizzate, più o meno come il glossario di un libro indica la pagina in cui appare una determinata parola.
INDICI
Consideriamo la seguente query:
Possono esserci più di 10000 film prodotti dalla Disney ma, solo 200, prodotti nel 1990
Risulta molto piu’ efficiente per prima cosa cercare i film prodotti nel 1990 e dopo controllare il valore contenuto nel campo studio.
SELECT * FROM imdb.”Movie” WHERE “studioName”=‘Disney’ AND “year”=1990
INDICI
La sintassi per la creazione degli indici è la seguente
La sintassi per l’eliminazione di indici è la seguente
CREATE INDEX nomeIndice ON NomeTabella(nomeCampo)
DROP INDEX nomeIndice
INDICI
La selezione degli indici richiede una riflessione da parte del database designer. Due importanti fattori da considerare sono:
Un indice su un attributo accellera notevolmente le query in cui quell’attributo e’ specificato.
Le inserzioni, cancellazioni e modifiche sulle tabelle sulle quali sono stati creati degli indici sono piu’ complesse e richiedono maggior tempo.
INDICI
Una strategia generale:
Se su una tabella vengono effettuate query più frequentemente di modifiche, allora specificare degli indici su questa tabella ha senso.
Se le modifiche sono predominanti rispetto alle query, dovremo porre molta attenzione alla creazione degli indici