Newsgroup: it.comp.lang.visual-basic
Titolo: Chiarimenti su tabelle e chiavi

Ciao,
facciamo le cose semplici. Ho due tabelle SQL Server Express:
Tabella1
--------
+ IDtab1
+ campo_pippo
+ IDtab2
Tabella2
--------
+ IDtab2
+ campo_abc
+ campo_def
I campi IDtab1 e IDtab2 sono chiavi primarie (isIdentity, autoincrement) 
delle rispettive tabelle. Uso il campo IDtab2 nella *Tabella1* per 
recuperare il record nella Tabella2.
Da un punto di vista logico esiste una relazione molti-a-uno tra la 
Tabella1 e la Tabella2.
Domande:
1) che vantaggio ho in termini di semplicità del codice/affidabilità a 
creare una relazione pk/fk tra le due tabelle? Ripeto devo solo 
recuperare il record in Tabella2 dato un record in Tabella1. In altre 
parole, come si usa dal punto di vista del codice la relazione creata?
2) non mi è chiaro cosa comporta a una chaive essere pk o fk.
Grazie a chi vorrà dedicarmi del tempo,
Marco / iw2nzm

 2) non mi è chiaro cosa comporta a una chaive essere pk o fk.
Pk significa che è la chiave di individuazione del record. Generalmente 
è anche indicizzata clustered, ma potrebbe anche essere del tutto 
sbagliato, va sempre verificato.
Fk significa che 'punta' fuori, ma a parte questo è un campo come tutti 
gli altri.
Ciao
Alberto
-- 
A questo punto hanno trovato un muro,
un muro duro, molto molto duro,
che siamo noi.

 gli altri.
Se ho ben capito, rifacendomi all'esempio di prima:
Tabella1
--------
+ IDtab1
+ campo_pippo
+ IDtab2
Tabella2
--------
+ IDtab2
+ campo_abc
+ campo_def
in Tabella1 IDtab2 risulta fk mentre in Tabella2 pk. E' corretto?
Grazie per la pazienza, come al solito!
Marco / iw2nzm

 in Tabella1 IDtab2 risulta fk mentre in Tabella2 pk. E' corretto?
Esatto.
Se vuoi vedere bene queste cose, imposta le relazioni col tool grafico, 
poi fatti generare gli script di CREATE TABLE, così tutte le constraint 
(siano esse PK, FK, Unique, Index, Default, Nullable, Collation, 
ecc...) ti vengono evidenziate in chiaro, campo per campo.


 parole, come si usa dal punto di vista del codice la relazione creata?
Non sono molto esperto ma...
Le relazioni ti servono per l'integrità dei dati.
Cioè diciamo
Tabella ANAGRAFICA
Codice Fiscale
e un'altra tabella che ho come FK il codice fiscale.
In questa tabella potrai mettere solo codifi fiscali presenti in ANAGRAFICA
o NULL, e a seconda di come imposti puoi fare in modo che se cambi il
codice fiscale questo viene automaticamente modificato nella tabella
correlata e (ma qui occorre fare attenzione) quando cancelli una persona in
anagrafica, tutti i record della tua tabella possono essere cancellati o
settati a null.
Solitamente metto ON UPDATE cascade (in modo che si autoaggiorni) mentre ON
DELETE non faccio niente.
Almeno che non siano tabelle Strettamente collegate, tipo una tabella
ordini e una righi ordine.
Se elimini un ordine puoi cancellare tutti i righi relazionati, che
altrimenti non avrebbero più senso.
Almeno questo è quello che so :D

 2) non mi è chiaro cosa comporta a una chaive essere pk o fk.
Le relazioni sono un concetto. In pratica sono il collegamento tra due (o 
più) tabelle, tra loro logicamente correlate.
Il fatto che i db relazionali (appunto!) ti permettano di implementare 
questo concetto non deve confonderti.
La chiave esterna (fk) è , in tutto e per tutto, un campo come un altro col 
solo limite che deve avere come tipo di dato lo stesso della chiave primaria 
(pk) al quale deve essere collegato.( se pk è int, pure fk deve essere int 
...e cosi' via)
In pratica devi vedere la chiave esterna come un "deposito" dove memorizzi 
uno scalare o una stringa che potrà essere utilizzato poi per determinate 
operazioni relative alle tabelle del db, quali il mantenimento 
dell'integrità referenziale, il collegamento master/detail ecc.
Se "dichiari" queste relazioni al db (al db, non dentro il tuo programma, a 
parte il caso di 
ado.net
 disconnesso), allora sarà il motore stesso del 
database a svolgere in automatico certe operazioni che tu dichiarerai voler 
fare.
Nel tuo esempio, la tabella1 è la parte molti di una relazione uno a molti. 
La tabella2 è la parte uno della relazione.
Supponi di cancellare un record dalla tabella2 (dove per esempio idtab2=10) 
e che ci siano in tabella1 uno o più record con il campo idtab2 contenenti 
il valore 10.
Avresti una violazione dell'integrità, poichè idtab2 punta ad un record che 
non esiste! Dichiarando una relazione ed impostando le relative modalità di 
esecuzione, il db stesso si occuperà automaticamente ad esempio di eliminare 
anche tutti i record di tabella1 che contengono idtab2 =10, perchè si 
suppone che cancellando la parte uno di una relazione (il padre) pure tutta 
la parte molti(figlio) non abbia senso.Questo non sempre pero' è vero o 
voluto, e per questo motivo che tu puoi impostare la modalità di "lavoro" 
della relazione. Piu' importante invece se cambi la chiave primaria in 
tabella2. In questo caso, con la relazione dichiarata esplicitamente al db, 
verranno aggiornate automaticamente dal db tutte le righe di tabella1 nel 
campo idtab2.Senza che tu faccia niente.
Attenzione.
Non sei obbligato a dichiarare una relazione.
Anzi, in molti non lo fanno. Sarai tu, da codice, a tenere in considerazione 
il problema dell'integrità, e che manterrai a suon di "delete * from 
tabella1 where idtab2=@myId" o di update.
Addirittura potresti anche avere in tabella1 dei record che puntano (col 
campo idtab2) a niente....nessuno te lo vieta.Ma avresti molto probabilmente 
dei record che non servono assolutamente a nulla se non a farti aumentare le 
dimensioni della tabella.
Chiedo scusa per la lunga risposta, ma volevo essere chiaro il più 
possibile.
Umbe 

 Umbe 
Grazie anche a te per l'intervento.
Ora mi è tutto più chiaro! Quindi il dichiarare una relazione 
automatizza (a seconda delle proprietà impostate) i controlli 
sull'integrità. La 'navigazione' tra le tabelle, che ovviamente sfrutta 
i campi chiave, avviene con le solite query di SELECT. Bene, dovrei 
esserci :)
Ciao e grazie a tutti!
Marco / iw2nzm

 esserci :)
Tieni appunto conto che in un campo che ha una FK puoi mettere solo valori
che sono nella tabella collegata, oppure valori null (almeno in firebird mi
pare), quindi tienine conto in INSERT e UPDATE

 (a seconda delle proprietà impostate) i controlli sull'integrità....
Diciamo che in generale è cosi'.
La cosa cambia un po' con 
ado.net
 che lavora in modalità disconessa.
Quando espliciti una relazione con 
ado.net
 (e quindi NON nel database), come 
saprai tale relazione mantiene l'integrità del database "virtuale" gestito 
da dataset.
In 
ado.net
 pero' le relazioni vengono usate anche per mantenere la corretta 
sincronia nelle form master/detail. Ad esempio, supponendo che i details 
vengano visualizzati da una datagrid (di solito è cosi'), imposterai come 
datasource il dataset, ma come datamember la RELAZIONE creata tra le due 
tabelle, collegate appunto con una pk e fk.
In pratica è come se usassi una "select * from tabelladettaglio where fk=pk"
Saluti
Umbe