Vincoli di Integrità Antonella Poggi Dipartimento di informatica e Sistemistica Sapienza Università di Roma Progetto di Applicazioni Software Anno accademico 2010-2011 Questi lucidi sono stati prodotti sulla base del materiale preparato per il corso di Progetto di Basi di Dati da A. Calì e da D. Lembo.
Generalità I vincoli di integrità specificano proprietà dei dati I vincoli restringono l insieme delle istanze possibili su uno schema, allo scopo di riflettere meglio il dominio che i dati medesimi rappresentano Nella definizione di uno schema, occorre specificare tutti i vincoli che devono sussistere sulle istanze dello schema Occorre specificare vincoli di integrità: sullo schema concettuale sullo schema logico Antonella Poggi 1
Vincoli sullo schema concettuale Vincoli di identificazione Vincoli di cardinalità Vincoli esterni Antonella Poggi 2
Prima classificazione dei vincoli di integrità Sullo schema concettuale, possiamo classificare i vincoli a seconda che esprimano proprietà che devono essere soddisfatte da ogni stato, coppia di stati consecutivi, o insieme di stati dei dati: vincoli di stato: si riferiscono ad ogni stato dei dati vincoli di transizione di stato: si riferiscono a due stati consecutivi dei dati vincoli di sequenza di stati (temporali): si riferiscono a più di due stati (non necessariamente consecutivi) dei dati Antonella Poggi 3
Vincoli di stato Specificano delle proprietà statiche dei dati. Sia i vincoli di identificazione che i vincoli di cardinalità sono vincoli di stato. Si consideri il seguente schema ER. Antonella Poggi 4
Antonella Poggi 5
Esempi di vincoli esterni che possono essere classificati come vincoli di stato sono i seguenti. Il livello di un impiegato deve essere un intero tra 1 e 8. La somma dei salari di tutti gli impiegati non può superare un tetto M. Antonella Poggi 6
Vincoli di transizione di stato Questi vincoli riguardono due stati consecutivi dei dati. Facendo riferimento alla precedente entità Impiegato, esempi di vincoli esterni che possono essere classificati di transizione di stato sono i seguenti: Il salario di un impiegato non può essere incrementato di più del 5 per cento con una singola operazione di aggiornamento. Il salario medio non può essere incrementato di più del 5 per cento con una singola operazione di aggiornamento. Un impiegato può diventare un pensionato ma non viceversa. Antonella Poggi 7
Vincoli temporali Questi vincoli riguardono un insieme di più di due stati non necessariamente consecutivi. Ad esempio (facendo sempre riferimento allo scenario precedente), vincoli esterni che possono essere classificati come vincoli temporali: Una volta che un impiegato è stato licenziato da un dipartimento, non può più essere impiegato in quel dipartimento. Il salario medio di un impiegato non può incrementare di oltre il 10% in meno di 10 operazioni di aggiornamento. Prima di diventare pensionato, un impiegato deve aver assunto almeno 3 diversi livelli di impiego. Antonella Poggi 8
Vincoli sullo schema logico Nel passaggio dallo schema concettuale allo schema logico, i vincoli sono anch essi tradotti in vincoli espressi in termini dello schema logico (i.e., relazionale). Lo schema relazionale risultante dalla traduzione è quindi corredato da un insieme di vincoli: vincoli di chiave (primaria e no) - risultanti, per esempio, dalla traduzione dei vincoli di identificazione o da cardinalità massime pari a 1 (i.e., funzionalità); attributi obbligatori - risultanti dalla traduzione dei vincoli di cardinalità minima pari a 1; vincoli di chiave esterna (foreign key) - risultanti, per esempio, da tipizzazione di relazioni, da vincoli esterni Antonella Poggi 9
introdotti sull ER dopo ristrutturazione delle ISA, o da decomposizioni di tabelle nella fase di ristrutturazione del logico; vincoli di inclusione - risultanti, per esempio, dalla traduzione di vincoli di cardinalità minima pari a 1 sulle relazioni; vincoli di disgiuntezza - risultanti, per esempio, dalla traduzione di generalizzazioni; vincoli di completezza - risultanti, per esempio, dalla traduzione di generalizzazioni complete; altri vincoli esterni - risultanti dalla traduzione di vincoli esterni espressi sull ER. Antonella Poggi 10
Ulteriore classificazione dei vincoli di integrità Sullo schema logico, è possibile classificare i vincoli, oltre che secondo il criterio precedente, a seconda che esprimano proprietà che devono essere soddisfatte da ogni tupla, tabella o insieme di tabelle: vincoli di tupla (riga): si riferiscono alle singole righe di una tabella vincoli di tabella: si riferiscono all insieme delle righe di una tabella vincoli inter-tabella: sono i più generali, e si riferiscono a più di una tabella Antonella Poggi 11
Vincoli di tupla Specificano delle proprietà che devono essere soddisfatte da ogni singola tupla di una tabella. I vincoli di attributi obbligatori sono vincoli di tupla. Siano ora Impiegato, Dipartimento e Pensionato le tabelle dello schema logico derivanti dalla traduzione della porzione dello schema ER vista in precedenza (sono state accorpate nella tabella Impiegato sia la ER-relazione lavora che la ISA derivante dalla generalizzazione). La tabella Impiegato ha attributi Codice, Nome, Cognome, Livello, Salario, Dipartimento. I seguenti vincoli, derivanti anch essi dalla traduzione dei vincoli sull ER, sono ulteriori esempi di vincoli di tupla: Antonella Poggi 12
Il livello di un impiegato deve essere un intero tra 1 e 8. Il salario di un impiegato non può essere incrementato di più del 5 per cento con una singola operazione di aggiornamento. Una volta che un impiegato è stato licenziato da un dipartimento, non può più essere impiegato in quel dipartimento. Antonella Poggi 13
Vincoli di tabella Specificano delle proprietà che devono essere soddisfatte dall insieme delle tuple di una tabella. I vincoli di chiave sono vincoli di tabella. Facendo riferimento alla tabella Impiegato, esempi di vincoli di tabella sono: La somma dei salari di tutti gli impiegati non può superare un tetto M. Il salario medio non può essere incrementato di più del 5 per cento con una singola operazione di aggiornamento Il salario medio di un impiegato non può incrementare di oltre il 10% in meno di 10 operazioni di aggiornamento. Antonella Poggi 14
Vincoli inter-tabella Specificano delle proprietà che devono essere soddisfatte dalle tuple di un insieme di tabelle. I vincoli di chiave esterna e di inclusione sono vincoli inter-tabella. Un impiegato può diventare un pensionato ma non viceversa. Prima di diventare pensionato, un impiegato deve aver assunto almeno 3 diversi livelli di impiego. Antonella Poggi 15
Specifica dei vincoli È opportuno che i vincoli siano specificati in modo dichiarativo, e cioè facendo riferimento a proprietà dei dati, e non a operazioni che consentano il soddisfacimento di dette proprietà. Si può usare una descrizione precisa in linguaggio naturale, oppure formalismi ad-hoc ad es., Object Constraint Language - OCL di UML I vincoli devono essere decomposti in vincoli elementari, in modo che possano essere facilmente implementati (come vedremo più avanti) Antonella Poggi 16
Consistenza dei vincoli Un insieme di vincoli si dice consistente se esiste almeno un istanza dello schema che li verifica tutti. In molti casi non è difficile definire vincoli non consistenti. Antonella Poggi 17
Ridondanza Un insieme di vincoli si dice ridondante se esiste in esso almeno un vincolo che implica un altro. È opportuno che non ci sia ridondanza nei vincoli definiti su uno schema. Antonella Poggi 18
Implementazione dei vincoli Implementare i vincoli significa assicurare che i dati si trovino sempre in uno stato consistente rispetto ai vincoli. In linea di principio, i vincoli devono essere implementati al livello di gestione dei dati (tramite gli strumenti del DBMS), affinché siano soddisfatti indipendentemente dalla modalità con cui si fa loro accesso. Quando, per scelta o a causa di limiti del DBMS, alcuni vincoli non sono implementati sulla base di dati, è necessario documentare in maniera adeguata la base di dati e delegare l implementazione dei suddetti vincoli alle applicazioni che accedono alla stessa. Antonella Poggi 19
Vincoli di integrità nel linguaggio SQL Per dichiarare vincoli di integrità possiamo usare i seguenti costrutti SQL: Costrutto NOT NULL : permette di definire attributi obbligatori Costrutto UNIQUE: permette di definire uno o più attributi che identificano la tupla Costrutto PRIMARY KEY: permette di definire uno o più attributi che formano una chiave primaria (implica NOT NULL) Costrutto FOREIGN KEY (REFERENCES): permette di definire chiavi esterne Costrutto CHECK: permette di definire vincoli generici intra-tabella Antonella Poggi 20
Costrutto CREATE ASSERTION: permette di definire vincoli generici inter-tabella Tranne CREATE ASSERTION, gli altri costrutti sono usati all interno dei comandi CREATE TABLE e ALTER TABLE. Antonella Poggi 21
I costrutti NOT NULL, UNIQUE e PRIMARY KEY (esempio) CREATE TABLE IMPIEGATO ( CODICE INT, NOME VARCHAR(20) NOT NULL, COGNOME VARCHAR(20) NOT NULL, LIVELLO INT NOT NULL, SALARIO INT NOT NULL, DIPARTIMENTO INT NOT NULL, PRIMARY KEY (CODICE, DIPARTIMENTO), UNIQUE (NOME, COGNOME) ); Antonella Poggi 22
Il costrutto FOREIGN KEY Consente di esprimere un vincolo di integrità referenziale (ad es., R 1 [A] R 2 [B], con B chiave di R 2 ) B può essere chiave primaria (PRIMARY KEY) o secondaria (UNIQUE) a partire da SQL99 consente di definire una politica di reazione alle modifiche (cancellazioni ed aggiornamenti) dei dati contenuti nella tabella esterna (R 2 ) che possono portare alla violazione del vincolo Antonella Poggi 23
Il costrutto FOREIGN KEY (cont.) per le cancellazioni si fa uso della clausola ON DELETE [CASCADE SET NULL SET DEFAULT NO ACTION RESTRICT] a fronte della cancellazione di una tupla nella tabella esterna, tutte le righe della tabella interna che referenziano la tupla cancellata vengono eliminate (opzione CASCADE), poste a NULL (SET NULL), poste al valore di default (SET DEFAULT). Con l opzione RESTRICT, se il vincolo risulta violato, si impedisce la cancellazione. Antonella Poggi 24
L opzione NO ACTION Le opzioni NO ACTION e RESTRICT sono tra loro molto simili. Infatti, se la verifica del vincolo fallisce, sia in caso di utilizzo dell opzione NO ACTION che in caso di utilizzo di RESTRICT, l operazione porta ad un errore. La principale differenza tra le due è che con l opzione NO ACTION, la verifica del vincolo di integrità è fatta dopo aver tentato di modificare la tabella esterna, mentre con l opzione RESTRICT la verifica è fatta prima di tentare l esecuzione del DELETE. Antonella Poggi 25
Il costrutto FOREIGN KEY (cont.) per gli aggiornamenti si fa uso della clausola ON UPDATE [CASCADE SET NULL SET DEFAULT NO ACTION RESTRICT] a fronte dell aggiornamento della chiave della tabella esterna, all attributo delle corrispondenti tuple della tabella interna viene assegnato lo stesso nuovo valore (CASCADE), il valore NULL (SET NULL) oppure il valore di default (SET DEFAULT). Con l opzione RESTRICT si impedisce l aggiornamento. L opzione NO ACTION ha la stessa semantica descritta per le cancellazioni. Antonella Poggi 26
Il costrutto FOREIGN KEY (esempio) CREATE TABLE IMPIEGATO ( CODICE INT, NOME VARCHAR(20) NOT NULL, COGNOME VARCHAR(20) NOT NULL, LIVELLO INT NOT NULL, SALARIO INT NOT NULL, DIPARTIMENTO INT NOT NULL REFERENCES DIPARTIMENTO (COD_DIP) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY (CODICE, DIPARTIMENTO), UNIQUE (NOME, COGNOME) ); Antonella Poggi 27
Il costrutto DEFAULT Nei casi in cui per specificare la reazione ad una cancellazione o ad una modifica si ricorre alla clausola SET DEFAULT, è necessario che sia previsto un valore di default da assegnare all attributo che eventualmente rimane appeso. Nell istruzione CREATE TABLE si usa la seguente sintassi: <Nome Colonna> <tipo SQL> DEFAULT <expression> Quando si definisce un valore di default per una colonna, tale valore viene assegnato quando si inserisce una tupla senza specificare alcun valore per l attributo in oggetto Antonella Poggi 28
Il costrutto DEFAULT (esempio) CREATE TABLE IMPIEGATO ( CODICE INT, NOME VARCHAR(20) NOT NULL, COGNOME VARCHAR(20) NOT NULL, LIVELLO INT DEFAULT 1 NOT NULL, SALARIO INT NOT NULL, DIPARTIMENTO INT NOT NULL REFERENCES DIPARTIMENTO (COD_DIP) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY (CODICE, DIPARTIMENTO), UNIQUE (NOME, COGNOME) ); Antonella Poggi 29
Il costrutto CHECK Consente di esprimere vincoli di integrità complessi su una sola tabella: CHECK (<condizione>) dove <condizione> è una qualsiasi condizione che può comparire all interno di una clausola WHERE (incluse quelle che fanno uso di sub-query) Consente di implementare vincoli a livello di tupla (ad esempio, SALARIO >= 0) e di tabella (in genere tramite sub-query con operatori aggregati). Antonella Poggi 30
Esempio CREATE TABLE IMPIEGATO ( CODICE INT, NOME VARCHAR(20) NOT NULL, COGNOME VARCHAR(20) NOT NULL, LIVELLO INT DEFAULT 1 NOT NULL CHECK (LIVELLO <= 8 AND LIVELLO >=1), SALARIO INT NOT NULL CHECK (SALARIO >=0), DIPARTIMENTO INT NOT NULL REFERENCES DIPARTIMENTO (COD_DIP), PRIMARY KEY (CODICE, DIPARTIMENTO), UNIQUE (NOME, COGNOME), CHECK (50 > (SELECT AVG(SALARIO) FROM IMPIEGATO)) ); Antonella Poggi 31
Il comando ALTER TABLE In alternativa alla sintassi descritta fin qui per definire vincoli, si può usare il comando ALTER TABLE: ALTER TABLE <Nome tabella> ADD <{PRIMARY KEY FOREIGN KEY UNIQUE CHECK}> Tale comando è utile per realizzare vincoli di integrit referenziali ciclici: per far sì che R 1 referenzi R 2 ed R 2 referenzi R 1 si può definire prima R 1 senza vincolo di foreign key (altrimenti si dovrebbe far riferimento ad R2 che non è stata ancora definita), poi R 2 con il vincolo di foreign key verso R 1, ed infine aggiungere il vincolo di foreign key ad R 1 con il comando ALTER TABLE Antonella Poggi 32
Il costrutto ASSERTION Per i vincoli inter-tabella, il costrutto CREATE ASSERTION permette di definire vincoli a livello di schema: CREATE ASSERTION <NomeAss> CHECK (<condizione>); Antonella Poggi 33
Esempio (vincolo di inclusione) vincolo: Ogni impiegato risiede in almeno una città (supponiamo che esista una tabella RISIEDE IN(IMPIEGATO,CITTA), con chiave su entrambe le colonne) CREATE ASSERTION impiegato_risiede CHECK (NOT EXISTS (SELECT * FROM IMPIEGATO WHERE CODICE NOT IN (SELECT IMPIEGATO FROM RISIEDE_IN) ); Antonella Poggi 34
Assegnare nomi espliciti a vincoli in SQL Tutti i vincoli di integrità (tranne i vincoli sugli attributi obbligatori) hanno un nome unico all interno di uno schema. Se il nome non è specificato esplicitamente, viene assegnato dal sistema secondo una modalità dipendente dall implementazione. Esplicitare il nome di un vincolo può essere conveniente, per esempio, quando si prevede la necessità di eliminare il vincolo stesso (con l istruzione DROP CONSTRAINT <Nome Vincolo>) Antonella Poggi 35
Per esplicitare il nome di un vincolo: nell istruzione CREATE TABLE, si usa la sintassi CONSTRAINT <NomeVincolo> [ PRIMARY KEY UNIQUE FOREIGN KEY CHECK ]; nell istruzione ALTER TABLE, si usa la sintassi ADD CONSTRAINT <NomeVincolo> [ {PRIMARY KEY UNIQUE FOREIGN KEY CHECK} ]; Antonella Poggi 36
CREATE TABLE IMPIEGATO ( NOME VARCHAR(20) NOT NULL, COGNOME VARCHAR(20) NOT NULL, LIVELLO INT CHECK (LIVELLO <= 8 AND LIVELLO >=1), SALARIO INT CHECK (SALARIO >=0), DIPARTIMENTO INT, CONSTRAINT imp_fk FOREIGN KEY (DIPARTIMENTO) REFERENCES DIPARTIMENTO(COD_DIP), CONSTRAINT imp_pk PRIMARY KEY (CODICE, DIPARTIMENTO), CONSTRAINT imp_k UNIQUE (NOME, COGNOME), CONSTRAINT imp_max CHECK (50 > (SELECT AVG(SALARIO) FROM IMPIEGATO)) ); Antonella Poggi 37
Modalità di verifica di vincoli Ogni vincolo è caratterizzato da una modalità di verifica (checking mode), che determina il momento in cui il vincolo viene verificato: nel caso in cui la modalità sia IMMEDIATE il vincolo è controllato dopo l esecuzione di ogni comando SQL; se la modalità è DEFERRED il vincolo è verificato solo al termine della transazione corrente La modalità deferred può essere applicata solo ai vincoli che, al momento della loro creazione, sono stati definiti DEFERRABLE (N.B. Se non si specifica nulla, un vincolo viene implicitamente definito come NON DEFERRABLE). Se un vincolo è inizialmente definito DEFERRABLE, allora si deve specificare la sua modalità di verifica iniziale: Antonella Poggi 38
CONSTRAINT <NomeVincolo> [ PRIMARY KEY UNIQUE FOREIGN KEY CHECK ] [DEFERRABLE INITIALLY IMMEDIATE INITIALLY DEFERRED NON DEFERRABLE]; per modificare la modalità di verifica di un vincolo inizialmente definito DEFERRABLE, si usa la sintassi: SET CONSTRAINT <NomeVincolo> [DEFERRED IMMEDIATE]; Antonella Poggi 39
Esempio CREATE TABLE IMPIEGATO ( CODICE INT, NOME VARCHAR(20), COGNOME VARCHAR(20), LIVELLO INT CHECK (LIVELLO <= 8 AND LIVELLO >=1), SALARIO INT CHECK (SALARIO >=0), DIPARTIMENTO INT, PRIMARY KEY (CODICE, DIPARTIMENTO), UNIQUE (NOME, COGNOME), CHECK (50 > (SELECT AVG(SALARIO) FROM IMPIEGATO)) CONSTRAINT imp_fk FOREIGN KEY (DIPARTIMENTO) REFERENCES DIPARTIMENTO(COD_DIP) DEFERRABLE INITIALLY IMMEDIATE ); SET CONSTRAINT imp_fk DEFERRED; Antonella Poggi 40
MySQL vs. Standard SQL per l implementazione di vincoli MySQL consente di usare: Costrutto PRIMARY KEY Costrutto UNIQUE Costrutto FOREIGN KEY Costrutto NOT NULL Costrutto DEFAULT Non è possibile utilizzare il costrutto CHECK (questo impedisce la definizione dichiarativa di molti vincoli fra cui inclusione, completezza e disgiuntezza). Antonella Poggi 41
Un alternativa al costrutto CHECK Nei casi in cui si voglia forzare il valore di alcuni campi ad appartenere da un determinato insieme finito, è possibile usare un tipo enumerato ENUM. CREATE TABLE PERSONA( NOME VARCHAR(20), COGNOME VARCHAR(20), ETA INT, SESSO ENUM ( M, F ) ); In questo esempio, posso inserire tuple che abbiano nel campo SESSO esclusivamente i valori M, F, m, f. Antonella Poggi 42
MySQL ed il costrutto foreign key È possibile specificare le clausole ON {DELETE UPDATE} [{ CASCADE SET NULL RESTRICT NO ACTION}] Il comportamento di default è RESTRICT) L opzione NO ACTION si comporta in maniera analoga (differentemente dallo standard SQL) L opzione SET DEFAULT non è supportata Non è supportato l uso della clausola DEFERRABBLE tutti i vincoli sono verificati dopo l esecuzione di ogni comando SQL! Antonella Poggi 43
Esempio Contratto(cod fiscale, tipo, importo) PartitaIVA(cod fiscale, numero) Vincolo di chiave esterna: PartitaIVA[cod fiscale] Contratto[cod fiscale] (foreign key) Vincoli esterni: 1. Contratto[tipo] {C,P} i.e., ogni contratto deve essere di tipo C o P ( CoCoCo o Prestazione Professionale ) 2. Contratto[importo] 10.000 i.e., l importo di un contratto deve essere al più pari a 10.000 Antonella Poggi 44
3. cf,t,i,n Contratto(cf,t,i), PartitaIVA(cf,n) t= P i.e., tutte le tuple di Contratto che riguardano soggetti con partita IVA corrispondono a prestazioni professionali 4. cf,i Contratto(cf, P, i) n PartitaIVA(cf,n) i.e. tutte le tuple di Contratto che corrispondono a prestazioni professonali riguardano soggetti che hanno partita IVA Antonella Poggi 45
Implementazione dei vincoli 1. PartitaIVA[cod fiscale] Contratto[cod fiscale] Vincolo di stato / Vincolo inter-tabella Vincolo di foreign key: è necessario fare un attenta analisi del dominio per definire come reagire agli inserimenti nella tabella PartitaIVA: una soluzione semplice ed in questo caso soddisfacente è quella di delegarne la gestione al costrutto FOREIGN KEY un inserimento va a buon fine se esiste un contratto relativo al soggetto gli aggiornamenti/cancellazioni nelle tabelle Contratto/PartitaIVA: e.g. utilizzando le opzioni ON DELETE CASCADE, ON UPDATE CASCADE Antonella Poggi 46
2. Contratto[tipo] {C,P} Vincolo di stato / Vincolo di tupla Implementato tramite un tipo enumerato (costrutto ENUM). Antonella Poggi 47
Creazione tabelle codice SQL create table CONTRATTO( cod_fiscale CHAR(16) primary key, tipo ENUM ( I, P ) NOT NULL, importo INT NOT NULL ); create table PARTITAIVA( cod_fiscale CHAR(16) primary key, numero varchar(20) NOT NULL UNIQUE ); alter table PARTITAIVA add constraint fk_partitaiva foreign key (cod_fiscale) references CONTRATTO(cod_fiscale) on delete cascade on update cascade; Antonella Poggi 48
Implementazione dei vincoli (Cont.) 3. Contratto[importo] 10.000 Vincolo di stato / Vincolo di tupla 4. cf,t,i,n Contratto(cf,t,i), PartitaIVA(cf,n) t= P Vincolo di stato / Vincolo inter-tabella 5. cf,i Contratto(cf, P, i) n PartitaIVA(cf,n) Vincolo di stato / Vincolo inter-tabella I vincoli 3,4 e 5 non si possono implementare seguendo un approccio dichiarativo! Antonella Poggi 49
Quando un vincolo non può essere implementato in maniera dichiarativa, ovvero non si ha a disposizione alcun costrutto SQL che ne gestisca il soddisfacimento ad ogni inserimento/aggiornamento/cancellazione nelle tabelle coinvolte, è necessario fare un analisi accurata del da farsi in corrispondenza delle operazioni critiche, e definire apposite politiche di reazione. Vedremo più avanti come implementarli con un approccio procedurale... Antonella Poggi 50