View Full Version : [basi di dati] relazioni 1 a 1
nuovoUtente86
10-04-2008, 19:22
Stavo lavorando su una base di dati di un sito web e mi è saltato fuori un dubbio sulle relazioni 1 a 1.Allora ho aperto diversi libri e manuali ma i dubbi mi sono aumenti!V posto l' esempio classico del libro
stato(nome)
presidente(nome, stato)
presidente(stato) --> stato(nome)
Ora il dubbio è: in questo modo effettivamente presidente partecipa ad una sola relazione con stato, ma nulla impedisce di creare altre occorrenze presidente, stato dove il presidente è ovviamente diverso, essendo chiave, ma lo stato potrebbe essere sempre uguale!Non riesco a capire dove sbaglio a ragionare!
Se vuoi forzare il vincolo 1 presidente 1 stato, metti una constraint sulla coppia di attributi.
E poi tieni a mente che il modello relazionale nella teoria non equivale alle varie implementazioni dei vari RDBMS. Non credo esista un db che soddisfi tutte le regole di Codd... a meno che non sia rimasto indietro (cosa probabile).
nuovoUtente86
10-04-2008, 20:23
Quello che mi serviva nella pratica l' ho forzato ponendo un attributo come chiave e l' altro con vincolo unique, però mi sembra strano come la teoria mostri questa mappatura che in realtà diventa 1 a molti invece di 1 a 1!
Infatti si potrebbe avere
STATO
Italia
Francia
Grecia
PRESIDENTE
Marco Italia
Luca Italia
Luigi Francia
Andrea Grecia
La doppia presenza di Italia consentita dalla mappatura viola la cardinalità!
Molto probabilmente sbaglio io, ma qualcosa non torna.
E' proprio cosi'.
I vincoli 1:1 vengono realizzati con chiave primaria sulla tabella padre, e con chiave straniera piu' vincolo unique sulla tabella figlio.
Nel tuo esempio sarebbe vincolo unique sulla colonna IDStato della tabella Presidente
I vincoli 1:1 identificativi invece sono gia' di per loro natura a posto, essendo che la chiave straniera parte gia' da una chiave primaria (e punta ad un'altra chiave primaria).
Es: TabellaAzienda, TabellaFornitore e TabellaCliente.
La tabella padre vorrebbe essere la TabellaAzienda, con PK = IDAzienda
La stessa PK sarebbe la stessa delle tabelle figlie.
Potrebbero essere organizzate cosi' quando p.es. i campi dei fornitori possono essere diversi dai campi dei clienti, ma dove almeno c'e' un servizio che fa uso dei campi comuni (presenti tutti in TabellaAzienda)
nuovoUtente86
10-04-2008, 20:44
Effettivamete quella del vincolo unique è l' unico modo per forzare quetso tipo di relazione, ma come mai viene "taciuto" in tutti i libri?
Nel tuo secondo esempio se ho capito bene la PK è uguale per tutte le 3 tabelle?In pratica si tratta di una generalizzazione tradotta in relazioni!
Effettivamete quella del vincolo unique è l' unico modo per forzare quetso tipo di relazione, ma come mai viene "taciuto" in tutti i libri?
Non so cosa ci sia sull'Atzeni-Nigro-Voci a riguardo, ma sull Inmon, sul Kimball e sulla Sql-Reference della Oracle me li ricordo abbastanza bene.
Nel tuo secondo esempio se ho capito bene la PK è uguale per tutte le 3 tabelle?
Esatto. Ma non si possono fondere insieme perche' contengono appunto entita' con attributi diversi e non fondibili.
Esattamente come la derivazione tra oggetti.
nuovoUtente86
10-04-2008, 21:14
Ecco cosa dice un riassunto estratto dall' Atzeni-Ceri-Paraboschi-Torlone a riguardo:
Nel caso di associazione uno a uno con partecipazione obbligatoria per entrambe le entità (non (0,1) ma (1,1)), la traduzione segue le regole:
Una delle entita’ si traduce in una relazione (tabella) con lo stesso nome dell’entità, avente i suoi stessi attributi, per chiave il suo identificatore e che ingloba anche la chiave della altra entità (tale attributo diventa quindi una chiave esterna), più tutti gli eventuali attributi della associazione (come nel caso 1-n, l’associazione non avrà una tabella distinta).
L’entita’ restante si traduce in una relazione (tabella) con lo stesso nome dell’entità, avente i suoi stessi attributi, per chiave il suo identificatore
In base alle regole, sono possibili due soluzioni:
Direttore(Codice,Cognome,Stipendio,DipartimentoDiretto,InizioDirezione) Dipartimento(Nome,Telefono,Sede)
oppure
Direttore(Codice,Cognome,Stipendio)
Dipartimento(Nome,Telefono, Sede, Direttore, InizioDirezione)
Esiste in teoria l’opzione di fondere tutto in un’unica tabella; tale opzione viene però scartata perché se in sede di progettazione concettuale era stato deciso di avere due entità legate da una relazione, diventa inopportuno tornare indietro in sede di progettazione logica.
Qualora una delle entità partecipi alla associazione con cardinalità (0,1) ossia è un’entità con partecipazione opzionale, delle due soluzioni si preferisce quella in cui la associazione viene inglobata dall’altra entità (quella che partecipa con cardinalità (1,1)), questo per evitare i valori nulli che figurerebbero negli attributi relativi all’associazione qualora venissero inglobati nell’entità che partecipa con cardinalità (0,1):
Impiegato(Codice,Cognome,Stipendio)
Dipartimento(Nome,Telefono,Sede, Direttore,InizioDirezione)
Come dicevo questo è un riassunto del libro,ma ho controllato sul testo e neanche li si fa cenno al vincolo unique come unica strada per rispettare la cardinalità!
Lo stesso vale per molte dispense universitarie che nel 99% dei casi si rifanno proprio all' Atzeni.
Come dicevo questo è un riassunto del libro,ma ho controllato sul testo e neanche li si fa cenno al vincolo unique come unica strada per rispettare la cardinalità!
Lo stesso vale per molte dispense universitarie che nel 99% dei casi si rifanno proprio all' Atzeni.
Pensa che io non mi ricordo neppure di averli studiati all'universita' i vincoli unique, al di fuori della chiave primaria.
Per essere ancora piu' precisi occorrerebbe addirittura specificare il vincolo "NOT NULL" sulla tabella figlia.
Senza il vincolo "NOT NULL" e' solo una relazione 1:0, ma il pezzo da te messo non l'ha imposto (magari c'e' altrove).
Inoltre non resta una vera 1:1 neppure aggiungendo quest'utlimo vincolo.
Nel tuo disegno "arricchito" di prima, potrebbe sempre esistere uno stato senza presidente.
Come la mettiamo?
Come dicevo questo è un riassunto del libro,ma ho controllato sul testo e neanche li si fa cenno al vincolo unique come unica strada per rispettare la cardinalità!
Lo stesso vale per molte dispense universitarie che nel 99% dei casi si rifanno proprio all' Atzeni.
Si ma fidati che si fa cosi come ti abbiamo detto.
All'università ti dicono che il modello relazionale è cosi, cosi e cosi...ma della PRATICA l'università non sa niente. Il modello ER va bene per pensare ai problemi e a come rappresentarli, ma poi la traduzione in un rdbms non è 1:1 col modello relazionale. Un esempio l'hai portato tu, un altro sono le relazioni N:M (che in un db si risolvono infilando una tabella in mezzo), ecc....
nuovoUtente86
11-04-2008, 12:00
Pensa che io non mi ricordo neppure di averli studiati all'universita' i vincoli unique, al di fuori della chiave primaria.
Per essere ancora piu' precisi occorrerebbe addirittura specificare il vincolo "NOT NULL" sulla tabella figlia.
Senza il vincolo "NOT NULL" e' solo una relazione 1:0, ma il pezzo da te messo non l'ha imposto (magari c'e' altrove).
Inoltre non resta una vera 1:1 neppure aggiungendo quest'utlimo vincolo.
Nel tuo disegno "arricchito" di prima, potrebbe sempre esistere uno stato senza presidente.
Come la mettiamo?
Si esatto non parla neppure del vincolo "NOT nULL"!Si concentra molto sulla struttura delle tabelle e sulle key,che in un corso di base forse sono le cose fondamentali, però a mio modo di vedere...resta troppo incompleta la trattazione!
Effettivamente puo esistere, anche imponendo i vincoli di Unique e NOTNULL,
uno stato senza presidente!Come si puo risolvere non lo so proprio, ma tu avrai certamente una risposta!
nuovoUtente86
11-04-2008, 12:13
Si ma fidati che si fa cosi come ti abbiamo detto.
All'università ti dicono che il modello relazionale è cosi, cosi e cosi...ma della PRATICA l'università non sa niente. Si mi fido, e del resto ero giunto alle stesse conclusioni ragionando un po sullo schema!Poi è evidente la vostra preparazione in materia!
[Quote]Il modello ER va bene per pensare ai problemi e a come rappresentarli, ma poi la traduzione in un rdbms non è 1:1 col modello relazionale. Un esempio l'hai portato tu, un altro sono le relazioni N:M (che in un db si risolvono infilando una tabella in mezzo), ecc....
Giustissimo, anche perchè non tutti i dbms consentono poi le stessespecifiche!Nelle relazioni molti a molti anche nella traduzione relazionale si mette la tabella in mezzo solitamente!
nuovoUtente86
14-04-2008, 12:12
E' proprio cosi'.
I vincoli 1:1 vengono realizzati con chiave primaria sulla tabella padre, e con chiave straniera piu' vincolo unique sulla tabella figlio.
Nel tuo esempio sarebbe vincolo unique sulla colonna IDStato della tabella Presidente
I vincoli 1:1 identificativi invece sono gia' di per loro natura a posto, essendo che la chiave straniera parte gia' da una chiave primaria (e punta ad un'altra chiave primaria).
Es: TabellaAzienda, TabellaFornitore e TabellaCliente.
La tabella padre vorrebbe essere la TabellaAzienda, con PK = IDAzienda
La stessa PK sarebbe la stessa delle tabelle figlie.
Potrebbero essere organizzate cosi' quando p.es. i campi dei fornitori possono essere diversi dai campi dei clienti, ma dove almeno c'e' un servizio che fa uso dei campi comuni (presenti tutti in TabellaAzienda)
Riuppo la discussione con un altra domandina:
Ipotizzando una situazione simile a quella descritta da te come potrei imporre il fatto che una' azienda si possa trovare solo nella tabelle fornitore o solo nella tabella cliente.?
Riuppo la discussione con un altra domandina:
Ipotizzando una situazione simile a quella descritta da te come potrei imporre il fatto che una' azienda si possa trovare solo nella tabelle fornitore o solo nella tabella cliente.?
Non ho capito se si tratta di OR logico o di OR esclusivo.
L'OR logico, piu' classico e usato, penso si possa applicare a questo caso, essendo che e' possibile tipicamente che un'azienda possa essere sia fornitore che cliente.
In questo caso puoi usare il classico "pattern" (non si chiamavano ancora cosi') delle superclassi.
Fai una tabella comune "Aziende", con gli attributi comuni tra clienti e fornitori.
Tipicamente ID (anzi, necessario), Nome, anagrafica geografica, etc.
Due tabelle "Fornitore" e "Cliente", figlie di Azienda, con FK verso di essa.
Nei grafici E-R diagrammati in UML questa situazione si trova con a simbologia specifica, che e' la linea che parte dal padre (la superclasse) con il pallino pieno e che si divide prima di entrare nei figli con il pallino vuoto. In pratica le FK si fondono ad un certo punto del tracciato.
Per quanto riguarda invece l'OR esclusivo, e' sufficiente aggiungere un attributo alla superclasse, ovvero "TIPO", che puo' valere solo "F" (fornitore) o "C" (Cliente). (Check constraint, oppure di nuovo una tabella normalizzata che pero' non consiglio dati i soli 2 valori)
Sta poi a te estendere del caso gli attributi NON-comuni dei fornitori o dei clienti nelle opportune tabelle figlie come nella soluzione precedente.
In entrambi i casi le tabelle che hanno un campo che e' un' "Azienda generica" punteranno alla superclasse, altrimenti all'una o all'altra delle tabelle figlie, a seconda dei casi.
nuovoUtente86
14-04-2008, 14:54
In pratica devo imporre che se un' azienda( presente nella tabella genitore ovviamente) è presente nella tabella fornitore, non puo poi essere presente in quella cliente!
Vista proprio in maniera pratica: se dall' applicazione cerco di compilare un form di inserimento di un' azienda come cliente, questo mi deve essere impedito se l' azienda risulta gia fornitore!Posso farlo con vincoli a livello DB o devo lavorare sul codice?
La soluzione
Per quanto riguarda invece l'OR esclusivo, e' sufficiente aggiungere un attributo alla superclasse, ovvero "TIPO", che puo' valere solo "F" (fornitore) o "C" (Cliente). (Check constraint, oppure di nuovo una tabella normalizzata che pero' non consiglio dati i soli 2 valori)
Sta poi a te estendere del caso gli attributi NON-comuni dei fornitori o dei clienti nelle opportune tabelle figlie come nella soluzione precedente.
puo' andare bene?
Ogni Azienda sara' di un solo tipo. O fornitore oppure cliente.
nuovoUtente86
14-04-2008, 15:43
Lo schema diventerebbe cosi
Azienda
MiaAzienda F
TuaAzienda C
SuaAzienda C
...........
Fornitori
MiaAzienda pane 10kg
TuaAzienda latte 10L //non dovrebbe stare qui
Clienti
SuaAzienda uova 10
Il vincolo di integrità referenziale è rispettato,per rispettare quello sul tipo dovrei utilizzare una assertion?
C'e' qualcosa che non mi piace nell'esempio che hai fatto.
cosa sarebbero quei "pane", "latte", "Uova".
Quello che bisognerebbe modellare e' un'anagrafica pura.
Al momento dell'inserimento di un'Azienda, viene inserito un record Nell'azienda e un record o nella tabella fornitori o nella tabella clienti.
Al momento dell'inserimento del record se l'azienda esiste gia', sia che sia un fornitore sia che sia un cliente, viene sollevata un'eccezione.
non vorrei che tu stessi gia' modellando qualche tipo di relazione tra le aziende e cio' che fanno (ordini o supply, immagino).
Quelli vanno in un'altra tabella.
In questo esempio ho supposto che le Aziende hanno tutte un descrittivo, una P.IVA, un telefono e un comune di registrazione
Solo i fornitori hanno un telefono e un nome del contatto da chiamare (per fare gli ordini)
Solo i clienti invece hanno un comune+indirizzo di spedizione dei beni
Fornitore e cliente sono semplicemente estensioni di Azienda.
Poi ho provato a mettere giu' tre relazioni che puntassero verosimilmente alle 3 tabelle anagrafiche:
Ordini: Contiene sia gli ordini dei clienti verso di noi che gli ordini nostri verso i fornitori. Se si ha l'accortezza di scrivere i prezzi negativi per gli ordini verso i fornitori si possono fare le somme su base temporale, ottenendo quello che e' tipicamente il Backlog (before tax) delle aziende, ovvero appunto l'aspettativa di introiti al netto delle spese, su base temporale. Quello che ci si aspetta si trasformera' in fatture di ingresso o di uscita
FidelizzazioneClienti: Un record in questa tabella indica che e' stato spedito in un dato anno la pubblicita' al cliente.
Ovviamente punta direttamente ai clienti
Supplier: Un record in questa tabella indica che il fornitore e' in grado di supplire un determinato bene.
Ovviamente punta direttamente ai fornitori.
[Azienda]
IDAzienda
Desc
IDComune
Telefono
PIva
Tipo [F o C]
[Fornitore]
IDAzienda
TelContattoFornitore
NomeContattoFornitore
[Cliente]
IDAzienda
IDComuneDiSpedizione
IndirizzoSpedizione
[Ordini]
IDAzienda (FK Verso Azienda)
IDProdotto
Quantita'
Prezzo accordato
TempoLimite
[FidelizzazioneClienti]
IDAzienda (FK Verso Cliente)
Anno
[Supplier]
IDAzienda (FK Verso Fornitore)
IDProdotto
Per avere i soli ordini dei clienti e' sufficiente la
SELECT * FROM Ordini NATURAL JOIN Cliente
Per avere i soli ordini che abbiamo fatto ai fornitori e' sufficiente la
SELECT * FROM Ordini NATURAL JOIN Fornitore
Per avere tutti gli ordini, raggruppati per regione (della azienda interessata)
SELECT IDRegione,SUM(Prezzo)
FROM Ordini
NATURAL JOIN Azienda
NATURAL JOIN Regioni
GROUP BY IDRegione
nuovoUtente86
14-04-2008, 16:53
Scusa effettivamente mi sono accorto di aver sbagliato a spiegarti la situazione che è pressochè cosi
[Azienda]
IDAzienda
Desc
IDComune
Telefono
PIva
Tipo [F o C]
[FidelizzazioneClienti]
IDAzienda (FK Verso Azienda) (PK)
Anno
[Supplier]
IDAzienda (FK Verso Azienda) (PK)
IDProdotto
Non guardarla con la logica di business ma solo con lo schema tabelle...
Devo vincolare il fatto che se un' azienda si trova in fidelizzazione cliente non puo trovarsi in supply.
Tenendo le tabelle cosi' non ce la fai se non facendo storture, tipo un FK di due campi, fatta con l'unione dei due campi IDAzienda e Tipo.
Perche' non valuti la derivazione? Aggiungi le 2 tabelle Cliente e Fornitore.
nuovoUtente86
14-04-2008, 17:51
Tenendo le tabelle cosi' non ce la fai se non facendo storture, tipo un FK di due campi, fatta con l'unione dei due campi IDAzienda e Tipo.
Perche' non valuti la derivazione? Aggiungi le 2 tabelle Cliente e Fornitore.
Per ora vorrei risolvere velocemente con un' assertion del tipo
assertion ...... check(codAzienda non presente in Fidelizzazione)!
Per quello che mi serve dovrebbe bastare!
Se proprio vuoi farlo cosi' fallo almeno sulla tabella aziende (sfruttando proprio il campo Tipo) non sulla tabella "sorella".
Altrimenti se un'azienda non e' ancora presente ne nei fornitori ne nei clienti rischi alla prima volta di permettere il suo inserimento nella tabella sbagliata.
nuovoUtente86
14-04-2008, 18:26
Se proprio vuoi farlo cosi' fallo almeno sulla tabella aziende (sfruttando proprio il campo Tipo) non sulla tabella "sorella".
Altrimenti se un'azienda non e' ancora presente ne nei fornitori ne nei clienti rischi alla prima volta di permettere il suo inserimento nella tabella sbagliata.
Si effettivamente hai ragione!
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.