PDA

View Full Version : SQL Vincolo di integrità referenziale


misterx
15-03-2007, 11:17
ho due tabelle dove la prima, t1, possiede un ID definito come chiave primaria.
La seconda tabella, t2, possiede un attributo ID che è chiave esterna verso l'ID di t1.

Se ora inizio a popolare la mia base di dati, posso inserire valori nell'ID di t2 sse il medesimo valore è già presente in t1 però: se ad un tratto io decidessi di modificare un valore chiave di t1, vorrei che questo si propagasse alle restanti tabelle quindi, si devono aggiungere cose del tipo

ON UPDATE CASCADE etc......

Domanda: ma ON DELETE UPDATE vanno aggiunte solo alla tabella con la chiave esterna ?

Spero di essermi fatto capire

misterx
15-03-2007, 13:22
faccio un esempio che è meglio :D

t1(ID, DESCRIZIONE)
t2(NOME, INDIRIZZO, ID)

_Claudio
15-03-2007, 17:56
faccio un esempio che è meglio :D

t1(ID, DESCRIZIONE)
t2(NOME, INDIRIZZO, ID)

t2 che attributi chiave ha? (attento alla normalità)
comunque se mi ricordo bene... sì il cascade va solo quando dichiari ID che referenzia l'altro ID (in t1) allora metti come propagare le modifiche.

misterx
15-03-2007, 22:02
ho messo l'ID di t2 in italico per sottolineare che è chiave esterna di t1.

Ho fatto delle prove ed ho notato che di defaut ON UPDATE NO ACTION e similare viene aggiunto alla tabella referente e no a quella referenziata.

Il mio dubbio è nato in quanto, se ho una tabella t1 che fa per così dire da guida per la mia base di dati ed altre tabelle che contengono una chiave esterna verso la tabella t1, e ad un certo punto desidero modificare un valore di t1 che è chiave, non mi è consentito; invece volevo capire come sarebbe possibile ciò propagandolo poi anche a tutte le atre tabelle referenti.

misterx
16-03-2007, 07:53
cmq, ho fatto diverse prove ed ho notato che se specifico n tabelle figlie con ON UPDATE CASCADE, modificando un valore chiave questo si propaga a tutte le figlie però, è sufficiente che una delle tabelle abbia la specifica NO ACTION per bloccare il CASCADE; che voi sappiate, c'è un motivo per tale comportamento bloccante ?

mad_hhatter
16-03-2007, 08:06
no il vincolo on update cascade va messo su T1, e nn su t2. è il dbms che si arrangia a fare tutto

misterx
16-03-2007, 08:10
no il vincolo on update cascade va messo su T1, e nn su t2. è il dbms che si arrangia a fare tutto

è quello che pensavo anch'io, ma ad esempio Postgres di default i vincoli li aggiunge alle tabelle con la chiave esterna



CREATE TABLE t1 (
id integer PRIMARY KEY,
corso character(20)
);


CREATE TABLE t2 (
docente character(20),
giorni character(20),
id integer
FOREIGN KEY (id) REFERENCES t1(id) ON UPDATE CASCADE;
);



questa frase è poco chiara, tratta dal link sotto

Le clausole ON DELETE e ON UPDATE indicano quale azione deve essere compiuta nel caso in cui una tupla nella tabella referenziata venga eliminata o aggiornata.


Ma la tabella referenziata è la tabella padre o figlia ?

http://database.html.it/guide/lezione/1312/creare-il-database/

mad_hhatter
16-03-2007, 08:35
ok ho detto una cazzata, scusami... ho appena controllato un vecchio progetto universitario e in effetti il vincolo va messo sul referente... in questo modo, credo, puoi associare a tabelle diverse azioni diverse se lo stesso dato riferito viene modificato...

spiegami un po' meglio la faccenda delle n tabelle con una sola impostata su no action

mad_hhatter
16-03-2007, 08:36
referenziato = dato originario

referente = foreign key, dato il cui valore è preso da un dato di un'altra tabella

misterx
16-03-2007, 08:41
spiegami un po' meglio la faccenda delle n tabelle con una sola impostata su no action

stavo pensando che se definisco 10 tabelle e tutte le collego con la FOREIGN KEY alla tabella padre, quella con la PRIMARY KEY, se solo una delle 10 tabelle ha specificato la clausola ON UPDATE NO ACTION, tale vincolo si propaga anche a tutte le altre 9 tabelle anche se hanno specificato ON UPDATE CASCADE. Mi chiedevo il motivo di tale comportamento conservativo.



edit
ho provato proprio ora con 3 tabelle ed è sufficiente che una abbia specificato ON UPDATE NO ACTION che viene bloccata la propagazione dell'aggiornamento.

mad_hhatter
16-03-2007, 08:59
vado nel campo delle ipotesi... la clausola no action significa "impedisci la modifica"... di cosa? della chiave riferita!!! quindi viene bloccato tutto l'iter a monte perchè il valore riferito non può essere modificato.

non potresti avere un comportamento del tipo che in una tabella referente non viene aggiornato il dato mentre nelle altre si, perchè romperesti la integrità referenziale

misterx
16-03-2007, 09:12
ma non è strano che se su 10 tabelle una sola ha la clausola non action viene bloccato tutto ?

mad_hhatter
16-03-2007, 09:52
non è strano... almeno finchè è coerente con la semantica del progetto e gli intenti del progettista... semplicemente stai dicendo che tutte le tabelle tranne una accettano un update, l'ultima no e quindi l'update è vietato, ed è vietato nella tabella riferita. essendo vietato nella tab riferita, è bloccato PER OGNI altra tabella referente... sta al progettista decidere se questa configurazione ha senso o meno, ma a livello logico, cioè per il dbms, questo è l'unico comportamento corretto

misterx
16-03-2007, 09:54
non è strano... almeno finchè è coerente con la semantica del progetto e gli intenti del progettista... semplicemente stai dicendo che tutte le tabelle tranne una accettano un update, l'ultima no e quindi l'update è vietato, ed è vietato nella tabella riferita. essendo vietato nella tab riferita, è bloccato PER OGNI altra tabella referente... sta al progettista decidere se questa configurazione ha senso o meno, ma a livello logico, cioè per il dbms, questo è l'unico comportamento corretto

no, l'esatto contrario.
9 accettano l'update ed 1 no ed è sufficiente quell'unica tabella per evitare l'update su tutte le altre.

mad_hhatter
16-03-2007, 09:55
infatti, se tu hai
T1 -> dato originale, tabella riferita
T2 -> primo referente (cascade)
T3 -> secondo refernte (no action)

se modifichi il dato in T1 e potessi aggiornare in T2 e lasciare invece le cose come stanno in T3 perderesti l'integrità referenziale, perchè T3 avrebbe una tupla che potenzialmente riferisce un dato non più esistente (il vecchio valore)...
oppure, potresti cambiare in T2 poi passare in T3 e vedereil no action e bloccare tutto, ma il dato aggiornato in T2 che fine fa? di nuovo romperesti l'integrità referenziale

mad_hhatter
16-03-2007, 09:56
no, l'esatto contrario.
9 accettano l'update ed 1 no ed è sufficiente quell'unica tabella per evitare l'update su tutte le altre.

intendo che la config. è che 9 accettano e 1 no, e di conseguenza all'atto pratico, nessuna accetta

mad_hhatter
16-03-2007, 10:02
è come dire, ci sono 10 persone che devono decidere se approvare una variazione... 9 dicono "per me è lo stesso", 1 dice "no, io non posso accettare" e quindi si decide per il no.

la semantica del cascade nn è "accetta e basta", ma è "se altrove nn ci sono divieti, accetta"

misterx
16-03-2007, 10:18
intendo che la config. è che 9 accettano e 1 no, e di conseguenza all'atto pratico, nessuna accetta

infatti il DBMS accetta sse tutte le 10 tabelle sono di comune accordo.
Beh, è una caratteristica che al corso di basi di dati non era emersa.

mad_hhatter
16-03-2007, 11:52
beh neanche da me era emersa in effetti, ma da quanto abbiamo detto in precedenza penso nn possa che essere così... poi magari è una caratteristica del dbms, nn lo so, ma secondo me il comportamento non può che essere quello (nel caso di un no action)