Newsgroup: it.comp.software.database
Titolo: integrità referenziale incrociata

o mutua o reciproca, non sapevo come chiamarla.
Guardate queste 2 relazioni (ogni squadra ha un operaio come 
caposquadra):
create table operaio
(codice int primary key,
 squadra char(20)
foreign key squadra references squadra(codice))
create table squadra
(codice int primary key,
 caposquadra char(20)
foreign key caposquadra references operaio(codice))
se devo inserire un caposquadra devo per forza inserire un operaio 
con campo squadra null e poi una squadra con relativo caposquadra 
appena inserito e poi inserire nella tabella operaio la squadra.
Simile discorso se inserisco una squadra prima del relativo 
caposquadra.
Sbaglio io sono gli unici modi?
Stavo pensando di usare una tabella ausiliaria, ma aumenterebbe la 
memoria e non vorrei farlo.
cosa ne pensate?
-- 
minollo
http://www.youtube.com/watch?v=uuOc7Eopiw4

 memoria e non vorrei farlo.
Che e` una delle vie giuste. Se hai problemi di referenzialita`
incrociata, c'e` qualcosa di veramente sbagliato nella progettazione del
db
Enrico

Enrico 'Henryx' Bianchi wrote :

Che colpa ne ho io se ho squadre di operai in cui il caposquadra è un 
operaio e devo rappresentare operai e squadre separatamente?
Certo che posso inserire un'altra tabella, ma se dovessi sviluppare 
un'applicazione embedded per inserire un dato devo fare comunque 3 
update, quindi tanto vale risparmiare una tabella.
Come fate voi in questi casi?
-- 
minollo
http://www.youtube.com/watch?v=uuOc7Eopiw4

 memoria e non vorrei farlo.
Non mi sembra indispensabile: è una relazione uno a molti (da quanto 
scrivi un operaio appartiene solo a una squadra), non molti a molti.
Se così non fosse una tabella di correlazione è indispensabile.
Ciao.

 
Mi sa che ti stai complicando la vita.
Io partirei da qui:
CREATE TABLE operaio (
    id xxx PRIMARY KEY,
    nome char(60)
);
CREATE TABLE squadra (
    codice int PRIMARY KEY,
    membro xxx NOT NULL,
    FOREIGN KEY membro REFERENCES operaio(id)
);
CREATE TABLE capo_squadra (
    -- XXX primary key
    id_operaio xxx NOT NULL,
    codice_squadra int NOT NULL,
    FOREIGN KEY id_operaio REFERENCES operaio(id),
    FOREIGN KEY codice_squadra REFERENCES squadra(codice)
)
Ciao  Manlio Perillo

Manlio Perillo wrote :

ok, va bene, anche il suggerimento di Pablo, tuttavia vi chiederei un 
parere ugualmente: le integrità referenziali incrociate (passatemi il 
termine se non è quello corretto e se ne esiste un altro) bisogna 
assolutamente evitarle?
Non vi sono capitati casi in cui vi andavano bene e le avete 
accettate?
La tua soluzione aggiunge una tabella, io pensavo o mi aspettavo che 
mi avreste sconsigliato di aggiungerla per risparmiare memoria: ho 
sempre questa paranoia, la memoria, che ho paura di occupare a 
dismisura, visto che con i DB è una cosa critica.
buon proseguimento di domenica
-- 
minollo
http://www.youtube.com/watch?v=uuOc7Eopiw4

 )
Curiosità: perché una molti a molti?
La FK "id_operaio" non duplica l'informazione "membro" presente nella 
tabella "squadra"?

 che con i DB è una cosa critica.
IMHO è una tabella inutile (il caporeparto è un attributo dell'operaio, 
  non una entità esterna) ma Manlio potrebbe fornire motivazioni a cui 
non ho pensato :)

 accettate?
No, in quanto vi sono sempre strade alternative che risolvono il
problema sia in modo elegante che efficiente
Enrico



Ho assunto che una squadra è formata da N operai, e da 1 caposquadra.
Ciao  Manlio

 Ho assunto che una squadra è formata da N operai, e da 1 caposquadra.
Sì, questo mi sembrava l'assunto di base, da cui sono partito anch'io.
Quello che non mi è chiaro della tua soluzione è l'uso del campo 
"squadra.membro" (è una relazione 1->1, identifica il caposquadra?).
Continuo a vedere come superflua la tabella capo_squadra visto che, 
appunto, la relazione squadre -> operai è, come giustamente dici, una 
1->N (ergo basta una FK squadra nella tabella operai).
Mi sfugge qualcosa? :)

 
squadra.membro identifica tutti gli operai appartenenti ad una data 
squadra.
Quindi tale relazione individua i membri di una squadra, ma non il capo 
squadra, che ha bisogno di una relazione a parte.
A meno di non aggiungere un campo:
  is_caposquadra
nella relazione squadra.
Soluzione che non mi piace molto.
Ciao  Manlio

 cosa ne pensate?
Non un problema fondamentale IMHO, specie considerando che
nel caso di una terza tabella probabilmente avrai anche dei
benefici sotto forma di maggiore semplicita` di query, possibilita`
di avere attributi specifici etc...
bye

 Soluzione che non mi piace molto.
Posso chiedertene il motivo? Solo per curiosità personale (de 
gustibus...) ;)
Se dovessi usare una relazione N->N opterei per una cosa simile:
CREATE TABLE operaio (
     id xxx PRIMARY KEY,
     nome char(60)
);
CREATE TABLE squadra (
     codice int PRIMARY KEY,
     nome char(60)
);
CREATE TABLE operai_squadre (
     -- XXX primary key
     id_operaio xxx NOT NULL,
     codice_squadra int NOT NULL,
     is_caposquadra boolean,
     FOREIGN KEY id_operaio REFERENCES operaio(id),
     FOREIGN KEY codice_squadra REFERENCES squadra(codice)
)
Ciao.

 [...]
Ciao  Manlio

 di avere attributi specifici etc...
okeissimo.
ciao e grazie ancora
-- 
minollo
http://www.youtube.com/watch?v=uuOc7Eopiw4

 Come fate voi in questi casi?
Con i metodi che ti sono stati descritti
Enrico

 da una a tre
Tra l'altro, io nel risponderti ho fatto l'errore di ragionare come te a
numero di operazioni eseguite. Il ragionamento corretto e` valutare il
tempo totale della transazione e non il tempo di ogni singola operazione
(paradossalmente non dubito che vi siano casi in cui eseguire una
transazione formata da n operazioni sia piu` veloce dell'eseguire una
transazione formata da n-x operazioni)
Enrico

 eliminata questa possibilit�?
No, intendevo che siamo nel campo di quello che non risulta
vietato in teoria; ma siamo vicini al caso (e questo si che
sarebbe problematico) in cui due vincoli di int.ref. sussistono
tra PK-PK. 

 Mi piace tenere separate le diverse entità; mi sembra più naturale.
Concordo, basta non eccedere: se in un'azienda devo archiviare i 
dipendenti avrò una tabella "dipendenti", non una "operai", una 
"commerciali", una "impiegati"... :)
Ciao.