Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Integrità referenziale database Mysql, Dispense di Basi di Dati

Cenni sull'integrità referenziali da applicare su un database generale e nel caso più specifico su mySQL.

Tipologia: Dispense

2019/2020

Caricato il 20/05/2020

gabriele-galatola
gabriele-galatola 🇮🇹

1 documento

1 / 11

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Integrità dei dati
Con il termine integrità dei dati si intende, nell'ambito della sicurezza informatica e
delle telecomunicazioni, la protezione dei dati e delle informazioni nei confronti delle
modifiche del contenuto, accidentali oppure effettuate da una terza parte, essendo
compreso nell'alterazione anche il caso limite della generazione ex novo di dati ed
informazioni.
I dati e le informazioni possono essere sia scambiati tra un mittente ed uno o più
destinatari, sia memorizzati e/o archiviati su un generico supporto. L'integrità dei dati
garantisce la qualità del supporto che li contiene (ad es. CD, DVD...) o di un software,
ad esempio un database.
Insito nel concetto di integrità vi è la possibilità di verificare con assoluta certezza se
un dato o una informazione siano rimasti integri, ossia inalterati nel loro contenuto,
durante la loro trasmissione e/o la loro memorizzazione. In un sistema che garantisce
l'integrità, l'azione di una terza parte di modifica del contenuto delle informazioni
scambiate tra mittente e destinatario, viene quindi rilevata.
Maggiore sarà l'integrità dei dati e consequenzialmente maggiore sarà la possibilità di
esatta lettura/scrittura degli stessi e quindi di prevenzione degli errori.
Un vincolo di integrità dei dati è una proprietà che deve essere soddisfatta dalle istanze
di una base di dati. In generale a uno schema di base di dati si associa un insieme di
vincoli e si considerano corrette (lecite o ammissibili) solo le istanze che soddisfano
tutti i vincoli predefiniti.
Vincoli di dominio. Essi vengono implicitamente specificati quando un attributo viene
associato al corrispondente dominio: i valori dell'attributo devono appartenere al
relativo dominio.
Obligatorietà degli attributi. In SQL, per default, un attributo (non facente parte della
chiave primaria) è opzionale, cioè può assumere valori nulli. Per rendere obbligatorio
un attributo, cioè per fare in modo che il suo valore sia sempre diverso da NULL, si
usa il vincolo not null da usare come nel seguente esempio:
nome varchar(20) not null
Se il valore di un attributo obbligatorio non viene specificato in fase di inserimento di
una riga, il DBMS genera un errore. Si noti che non è necessario specificare un valore,
in fase di inserimento, per un attributo obbligatorio con valore di default diverso da
NULL.
pf3
pf4
pf5
pf8
pf9
pfa

Anteprima parziale del testo

Scarica Integrità referenziale database Mysql e più Dispense in PDF di Basi di Dati solo su Docsity!

Integrità dei dati

Con il termine integrità dei dati si intende, nell'ambito della sicurezza informatica e

delle telecomunicazioni, la protezione dei dati e delle informazioni nei confronti delle

modifiche del contenuto, accidentali oppure effettuate da una terza parte, essendo

compreso nell'alterazione anche il caso limite della generazione ex novo di dati ed

informazioni.

I dati e le informazioni possono essere sia scambiati tra un mittente ed uno o più

destinatari, sia memorizzati e/o archiviati su un generico supporto. L'integrità dei dati

garantisce la qualità del supporto che li contiene (ad es. CD, DVD...) o di un software,

ad esempio un database.

Insito nel concetto di integrità vi è la possibilità di verificare con assoluta certezza se

un dato o una informazione siano rimasti integri, ossia inalterati nel loro contenuto,

durante la loro trasmissione e/o la loro memorizzazione. In un sistema che garantisce

l'integrità, l'azione di una terza parte di modifica del contenuto delle informazioni

scambiate tra mittente e destinatario, viene quindi rilevata.

Maggiore sarà l'integrità dei dati e consequenzialmente maggiore sarà la possibilità di

esatta lettura/scrittura degli stessi e quindi di prevenzione degli errori.

Un vincolo di integrità dei dati è una proprietà che deve essere soddisfatta dalle istanze

di una base di dati. In generale a uno schema di base di dati si associa un insieme di

vincoli e si considerano corrette (lecite o ammissibili) solo le istanze che soddisfano

tutti i vincoli predefiniti.

Vincoli di dominio. Essi vengono implicitamente specificati quando un attributo viene

associato al corrispondente dominio: i valori dell'attributo devono appartenere al

relativo dominio.

Obligatorietà degli attributi. In SQL, per default, un attributo (non facente parte della

chiave primaria) è opzionale, cioè può assumere valori nulli. Per rendere obbligatorio

un attributo, cioè per fare in modo che il suo valore sia sempre diverso da NULL, si

usa il vincolo not null da usare come nel seguente esempio:

nome varchar(20) not null

Se il valore di un attributo obbligatorio non viene specificato in fase di inserimento di

una riga, il DBMS genera un errore. Si noti che non è necessario specificare un valore,

in fase di inserimento, per un attributo obbligatorio con valore di default diverso da

NULL.

Chiave primaria. E' possibile identificare una unica chiave primaria con il

vincolo primary key da usare nel seguente modo:

create table dipendente ( cf char(16) primary key, nome varchar(20), cognome varchar(20), )

Se il vincolo coinvolge più attributi è possibile aggiungerlo dopo la definizione degli

attributi come segue:

create table dipendente ( nome varchar(20), cognome varchar(20), dataDiNascita date, luogoDiNascita varchar(20), primary key (nome, cognome) )

Gli attributi della chiave primaria devono assumere valori univoci e devono essere

obbligatori. Per loro non occorre specificare il vincolo di obbligatorietà. Una

violazione di questo vincolo genera un errore.

Chiavi candidate. E' possibile specificare altre chiavi candidate con il

vincolo unique. La specifica delle chiavi candidate avviene come per le chiavi

primarie, ad esempio:

create table dipendente ( cf char(16) primary key, nome varchar(20), cognome varchar(20), unique (nome, cognome) )

Si noti che per la chiave primaria non occorre specificare il vincolo di univocità. I valori

assunti da una chiave candidata devono essere univoci ma possono essere nulli. (a

differenza di quanto accade per la chiave primaria). Una violazione di questo vincolo

genera un errore.

Chiavi esterne. Il vincolo di chiave esterna ( foreign key ) coinvolge due tabelle (che

possono essere due istanze della stessa tabella). La tabella che contiene la chiave

esterna è detta secondaria ( slave ), mentre la tabella a cui fa riferimento la chiave

esterna è detta principale ( master ). Gli attributi riferiti nella tabella principale devono

formare una chiave candidata , di solito la chiave primaria. Il vincolo specifica che ogni

valore non nullo della chiave esterna nella tabella secondaria deve corrispondere ad un

  • no action: nessuna azione viene intrapresa e viene generato un errore.

Per le operazione di cancellazione posso reagire come segue:

  • cascade: le corrispondenti righe della tabella secondaria vengono cancellate;
  • set null: alla chiave esterna della tabella secondaria viene assegnato il valore

nullo al posto del valore cancellato nella tabella principale;

  • set default: alla chiave esterna della tabella secondaria viene assegnato il

corrispondente valore di default al posto del valore cancellato nella tabella

principale;

  • no action: nessuna azione viene intrapresa e viene generato un errore.

La sintassi per specificare queste politiche usa i costrutti on update e on

delete come segue:

create table biglietteria ( nome varchar(20) primary key, indirizzo varchar(40) not null, teatro varchar(20) foreign key references teatro(nome) on update cascade on delete set null )

Come regola generale, per le modifiche si usa la politica on update cascade. Per

le cancellazioni si usa la politica on delete cascade per chiavi esterne di tabelle

che corrispondono a relazioni concettuali (ad esempio la tabella lavoro nel nostro caso

di studio) oppure ad entità deboli (ad esempio la tabella prenotazione) e la politica on

delete set null negli altri casi. La ragione è che nel primo caso vi è un forte

collegamento tra la tabella master e la tabella slave e dunque una cancellazione nella

tabella master dovrebbe provocare corrispondenti cancellazioni nella tabella slave.

Regole aziendali. Ulteriori vincoli, detti vincoli di integrità generici in quanto non

legati al modello relazionale, sono quelli imposti dalle regole aziendali. Tali vincoli

possono essere rappresentati in SQL in più modi: mediante il costrutto check nella

definizione di una tabella, mediante le asserzioni, oppure attraverso l'uso di regole

attive ( trigger ).

E' bene chiarire in anticipo che i vincoli di integrità generici rappresentano un

argomento contrastato. A differenza dei vincoli relazionali, gli strumenti per

specificare vincoli generici non sono stabilmente inseriti nello standard SQL (ad

esempio i trigger sono stati aggiunti sono nell'ultima versione di SQL dopo essere stati

disponibili per molto tempo nei DBMS). Di conseguenza, mentre i vincoli tipici del

modello relazionale sono supportati efficientemente da tutti i DBMS relazionali, gli

strumenti per specificare vincoli generici variano notevolmente tra i vari DBMS

disponibili e non sempre garantiscono l'efficienza del sistema risulante. E' quindi

fortemente consigliato accertarsi di quali siano e di come funzionino gli strumenti per

vincoli generici supportati dal DBMS prescelto.

Il costrutto check permette di specificare, mediante una condizione come quella che

può apparire nella clausola where di una interrogazione SQL, vincoli generici a

livello di di tabella o, mediante le asserzioni, a livello di schema di base di dati.

Si noti che un uso indiscriminato di questi vincoli appesantisce il carico del sistema in

quanto, solitamente, i DBMS garantiscono una implementazione efficiente solo per i

vincoli propri del modello relazionale.

Vediamo alcuni esempi. Supponiamo di avere le tabelle dipendente, teatro e lavoro. La

tabella lavoro associa i dipendenti ai relativi teatri. Un teatro può avere più dipendenti

e un dipendente può lavorare per più teatri. Supponiamo di voler esprimere un vincolo

massimo di partecipazione per un dipendente rispetto alla relazione lavoro: un

dipendente non può lavorare per più di due teatri. Questo vincolo può essere specificato

sulla tabella lavoro nel seguente modo:

create table teatro ( nome varchar(20) primary key, indirizzo varchar(40) not null ) create table dipendente ( cf char(16) primary key, nome varchar(20) not null, cognome varchar(20) not null, dataDiNascita date, luogoDiNascita varchar(30), capo char(16), foreign key capo references dipendente(cf) ) create table lavoro ( teatro varchar(20), dipendente char(16), primary key(teatro, dipendente), foreign key teatro references teatro(nome), foreign key dipendente references dipendente(cf), check(2 >= (select count(*) from lavoro L where dipendente = L.dipendente)) )

Il vincolo afferma che per ogni dipendente non ci possono essere più di due righe nella

tabella lavoro, quindi più di due teatri per cui il dipendente lavoro. Nella query di

cf char(16) primary key, nome varchar(20) not null, cognome varchar(20) not null, dataDiNascita date, luogoDiNascita varchar(30), capo varchar(20), foreign key capo references dipendente(cf), check (luogoDiNascita <> "Milano" or dataDiNascita < '1970- 01 - 01') )

Vediamo un esempio di vincolo che coinvolge più tabelle. Supponiamo di voler

specificare il seguente vincolo minimo di partecipazione: un teatro deve avere almeno

5 dipendenti. Possiamo scrivere la seguente asserzione:

create assertion vincoloDipendentiTeatro check ( not exists (select nome from teatro where nome not in (select teatro from lavoro)) and not exists (select count() from lavoro group by teatro having count() < 5) )

Il vincolo asserisce che non esistono teatri privi di dipendenti e, tra quelli che hanno

almeno un dipendente, non esistono teatri con meno di 5 dipendenti. Dunque tutti i

teatri hanno almeno 5 dipendenti.

Inoltre, vediamo un vincolo sulla cardinalità di una tabella. La seguente asserzione

afferma che ci devono essere almeno 3 teatri nella rete:

create assertion vincoloTeatriRete check ( 3 <= (select count(*) from teatro) )

Le regole attive ( trigger ) permettono di gestire i vincoli di integrità. La differenza

rispetto agli strumenti fin ora introdotti per specificare vincoli di integrità (relazionali

o generici) è la seguente: un trigger specifica una azione da intraprendere qualora in

vincolo non sia soddisfatto, solitamente una azione riparatrice della integrità violata.

Un trigger segue il paradigma evento-condizione-azione : se un certo evento si

verifica, la relativa condizione viene controllata e, se soddisfatta, l'azione viene

intrapresa. Un evento è solitamento un aggiornamento della base di dati (insert, update,

delete). Una condizione è un predicato espresso in SQL. Una azione è una

interrogazione SQL (solitamente di aggiornamento della base di dati) oppure una

eccezione che annulla gli effetti dell'operazione che ha attivato il trigger riportando la

base di dati allo stato precedente a tale operazione ( rollback ). Il trigger può essere

attivato prima o dopo l'evento.

Si noti che ci possono essere più trigger associati ad un evento. L' ordine di

esecuzione dei trigger in tal caso è gestito dal sistema e generalmente tiene conto

dell'ordine di creazione dei trigger. Un trigger che come azione aggiorna lo stato della

base di dati può a sua volta innescare altri trigger, che a loro volta possono attivare altri

trigger, con la possibilità di avere reazioni a catena infinite. Inoltre, l'azione di un

trigger può violare vincoli di integrità. La violazione di un vincolo di integrità di chiave

esterna può causare, come conseguenza delle politiche di gestione di tali vincoli,

ulteriori modifiche alla base di dati che al loro volta possono scatenare altri trigger,

oppure violare altri vincoli di integrità. Si badi bene che la violazione di un vincolo di

integrità non gestito, a qualsiasi livello della catena di attivazione, produce

un annullamento degli effetti di tutte le operazioni innescate dalla primitiva madre

che ha generato la catena di trigger, compresi gli effetti della primitiva madre stessa. I

trigger sono dunque strumenti semplici da scrivere in modo indipendente ma difficili

da gestire in modo integrato.

Supponiamo di voler specificare un trigger per il vincolo che afferma che lo stipendio

di un dipendente non può essere incrementato più del 20%:

create trigger LimitaIncrementoStipendio after update of stipendio on dipendente for each row when (New.stipendio > Old.Stipendio * 1.2) update dipendente set New.stipendio = Old.Stipendio * 1. where cf = New.cf

Il trigger LimitaIncrementoStipendio viene attivato dall'evento modifica (update) dello

stipendio di un dipendende. Per ogni riga modificata, se il nuovo stipendio è stato

incrementato più del 20% rispetto al vecchio (condizione when), allora lo stipendio

viene incrementato del massimo possibile senza violare il vincolo di integrità. Si noti

che è possibile usare le variabili di tupla New e Old per riferirsi, rispettivamente, alla

tupla dopo e prima la modifica. Per gli eventi di inserimento, solo New è accessibile,

per gli eventi di cancellazione, solo Old è accessibile.

Vediamo un altro esempio. Vogliamo modellare la regola che dice che una

prenotazione per uno spettacolo può essere effettuata solo se vi sono ancora posti a

disposizione in sala. Usiamo i seguenti quattro trigger:

create trigger disponibilità- 1 after insert on messaInScena for each row

I trigger sono anche utili per specificare le regole di calcolo degli attributi calcolati.

Supponiamo che il prezzo ridotto di uno spettacolo debba essere scontato del 20%

rispetto a quello intero. Dunque l'attributo prezzo ridotto è calcolato rispetto al prezzo

intero. I trigger per gestire questo vincolo seguono:

create trigger CalcolaPrezzoRidottoInsert after insert on messaInScena for each row update messaInScena set New.prezzoRidotto = New.prezzoIntero * 0. where codice = New.codice create trigger CalcolaPrezzoRidottoUpdate after update of prezzoIntero on messaInScena for each row update messaInScena set New.prezzoRidotto = New.prezzoIntero * 0. where codice = New.codice

Non tutti i vincoli di integrità possono essere descritti a livello di schema in SQL.

Solitamente, quando un vincolo non è descrivibile in SQL, esso viene catturato a livello

di applicazione implementandolo in qualche linguaggio di programmazione. E' bene

che tutti i vincoli esprimibili in SQL vengano definiti a livello di schema in modo da

renderli condivisi da tutte le applicazioni invece che replicare il vincolo per ogni

applicazione. In tal modo le modifiche di un vincolo sono gestite a livello di schema

senza modificare le applicazioni. Si parla in tal caso di indipendenza dalla

conoscenza , dove per conoscenza si intende l'insieme delle regole codificate nei

vincoli che regolano l'integrità della base.

E' possibile aggiungere e rimuovere vincoli di integrità definiti su una tabella mediante

il comando alter. Per rimuovere un vincolo occorre averlo definito per nome

mediante il costrutto constraint. Ad esempio:

create table dipendente ( cf char(16) primary key, nome varchar(20) not null, cognome varchar(20) not null, indirizzo varchar(30), constraint chiaveCandidata unique(nome, cognome) ) alter table dipendente drop constraint chiaveCandidata alter table dipendente add constraint chiaveCandidata unique(indirizzo)

Per rimuovere una asserzione o un trigger occorre usare il comando drop seguito dal

nome del costrutto.

Concludiamo la parte sulla definizione dei dati in SQL parlando brevemente

del catalogo dei dati. Il catalogo dei dati è una base relazionale per archiviare lo

schema fisico di una base di dati; tale base contiene una descrizione dei dati e non i

dati veri e propri. Ad esempio, il catalogo dei dati contiene una tabella per gli attributi

delle tabelle di uno schema fisico. Ogni riga della tabella specifica, tra l'altro, il nome

dell'attributo, la tabella di appartenenza, il suo valore di default e l'obligatorietà.

Il catalogo dei dati viene solitamente mantenuto dal DBMS e non deve essere creato o

modificato dall'utente. Il catalogo dei dati può però essere interrogato dall'utente.

Questo offre la possibilità interessante di costruire interrogazioni che accedano sia ai

dati che ai metadati. E' bene che i dati e i metadati vengano organizzati nel medesimo

modello dei dati (relazionale, ad oggetti, XML). In questo modo è possibile archiviare

dati e metadati con le stesse strutture e interrogarli con lo stesso linguaggio. Questa

caratteristica prende il nome di riflessività.