|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
[basi di dati] relazioni 1 a 1
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! |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
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).
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
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. |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
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)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
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! Ultima modifica di nuovoUtente86 : 10-04-2008 alle 20:47. |
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Quote:
Esattamente come la derivazione tra oggetti.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Ecco cosa dice un riassunto estratto dall' Atzeni-Ceri-Paraboschi-Torlone a riguardo:
Quote:
Lo stesso vale per molte dispense universitarie che nel 99% dei casi si rifanno proprio all' Atzeni. |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
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?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
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....
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
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! |
|
![]() |
![]() |
![]() |
#11 | ||
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
Quote:
|
||
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
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.? |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
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.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
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? |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
La soluzione
Quote:
Ogni Azienda sara' di un solo tipo. O fornitore oppure cliente.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
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? |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
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. Codice:
[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 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
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
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. |
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
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.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
assertion ...... check(codAzienda non presente in Fidelizzazione)! Per quello che mi serve dovrebbe bastare! |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:13.