Newsgroup: it.comp.software.database
Titolo: Uno a Uno ... da due tabelle

Ciao a tutti,
sono di nuovo qua a chiedere consigli, visto che i precedenti sono
stati di grande aiuto.
Mi trovo con una situazione strana, ovvero devo creare una tabella
"Certificati" che conterra dei documenti di certificazione.
Un record "Certificati" avrà una relazione uno-a-uno con la tabella
"Riparazioni", che contiene i processi di lavoro.
Il problema è che un "Certificato" può avere una relazione uno-a-uno
con la tabella delle "Vendite".
Io volevo mantenere una sola tabella per le certificazioni, ma come
faccio ad attribuire una chiave primaria? Avrei bisogno di una PK
composta, ma comunque il DB non sa a quale tabella punta la chiave,
essendo una relazione verso due tabelle distinte.
Avevo pensato di gestire tutto da codice, con un campo sulle
"Certificazioni" che identifica se deriva da "Riparazione" o da
"Vendite".
Come posso snellire il tutto?
SimoHack

In sostanza un Certificato può essere legato in maniera esclusiva O alla 
Vendita O alla Riparazione (ma non entrambi), giusto?
Credo che la soluzione più pulita sia con una tabella intermedia:
soluzione 1)
RelCertVendRip(idCertificato,idEvento,tipoEvento)
smisti in virtù del valore di tipoEvento (vendita piuttosto che 
riparazione) ma ti salta l'integrità
soluzione 2)
RelCertVendRip(idCertificato,idVendita,idRiparazione)
smisti in virtù del campo nullo che DOVRA' essere uno dei due. Forse 
riesci ad implementare una integrità lasca ma è comunque un potenziale 
rischio
In entrambi i casi, una restrizione di univocità di garantisce la 
relazione uno-a-uno anziché molto-a-molti
Alex.

Come posso snellire il tutto?
Una tabella in più = meno IF nel tuo codice, miglior data integrity
Ciao e buon lavoro
PS: la fattura te la mando all'indirizzo dell'altra volta
:-)

 :-)
"Pagamento Ns Solito" ;)
SimoHack

Potenzi la soluzione 2):
Vendite { PKVendita, dati... }
Riparazioni { PKRiparazione, dati... }
CertificatiPerVendita { FKCert, FKVendita }
CertificatiPerRiparazione { FKCert, FKRiparazione }
(con controlli univocità)
Certificati(PKCert, dati...)
Questo almeno è quello che otterresti sbrogliando l'eventuale E/R, 
elegante ma pesante.
Alex.

Ci provo,
potenziando la Soluzione 2 mi sembra OK.
Ringrazio tutti, davvero tutti.
SimoHack

 CertificatiPerRiparazione { FKCert, Tipo Check "R", FKRiparazione }
Ok, diciamo che togliendo il vincolo 1:1 obbligatorio ed impostando
un vincolo ref in più potrei forzare il seguente schema:
Certificati
-----------
1 V
2 R
3 V
4 V
CertificatiPerVendita
---------------------
1 V
3 V
4 V
CertificatiPerRiparazione
-------------------------
2 R
Risultati:
- ora lo schema non si pianta più se inserisco una riga solo in una
coppia di tabelle.
- il vincolo ref mi garantisce che il numero di certificato esista.
- la Pk su cert mi garantisce che il numero non sia duplicato.
- un vincolo Check mi garantisce che per ciascuna tabella, io possa
avere O un certificato di vendita O uno di acquisto, ma non entrambi.
- un vincolo ref doppio mi garantisce che la riga di Certificati vada
a "cadere" nella giusta tabella
Oooh, che bello, abbiamo risolto tutto quanto? Siamo riusciti
a "fregare" il database??
Solo se chiudiamo un occhio (ma anche due) sulla teoria: specificando
di che "tipo" è il certificato, abbiamo commesso un errore EAV !
Nella teoria relazionale, non si specifica di che tipo è una riga o
a quale tabella appartenga: è la presenza stessa della riga nella
giusta tabella che ne specifica il tipo!
E che cosa denotano differenti attributi? Differenti tabelle!
Questo errore punta l'indice proprio contro il fatto che abbiamo
conglobato due tabelle in una.
Dopo aver rigirato la frittata quattro volte, ho tratto queste
conclusioni:
1. Se ho bisogno di forzare una regola tramite codice, per la quale
   la funzionalità base dello schema non mi basta, si tratta di:
 1.1 Un errore di modellazione
 1.2 Una business rule (quindi non un problema di integrità dei dati
     dal punto di vista relazionale, per cui va risolta nel layer
     soprastante)
2. La teoria relazionale è coerente e non si riesce a fregarla :-p
3. Se devo fare il furbo, scelgo la via che mi dà il maggior vantaggio,
   tanto rigirare la frittata non serve
Ciao