PDA

View Full Version : [DATABASE] Domandina urgente circa cardinalità di una relazione


D4rkAng3l
16-02-2008, 15:33
Ciao,
per il progetto dell'esame di base di dati mi trovo a dover realizzare il DB di un piccolo sistema di aste online (una versione della baia molto semplificata).

Considerando queste due entità:

UTENTE: che rappresenta gli utenti iscritti al sistema e vendono o comprano oggetti

INSERZIONE: rappresenta gli oggetti messi in vendita dagli utenti.

Poi ho una relazione chiamata VENDE che lega insieme UTENTE e INSERZIONE (in pratica associa alcuni utenti ai prodotti che vendono).

In UTENTE ci saranno sia utenti venditori che utenti acquirenti.

Volendo gestire i feedback che gli acquirenti danno ai venditori circa il loro comportamento durante la vendita di un particolare oggetto (in pratica l'utente acquirente può dire al termine della vendita se il venditore siè comportato in maniera corretta, scorretta o neutra).

La relazione FEEDBACK_VENDITORE coinvolgerà: UTENTE, UTENTE (in maniera ricorsiva) e INSERZIONE.

In pratica un utente acquirente dà un feedback ad un utente venditore in relazione ad una ed una sola determinata inserzione.

Per quanto riguarda la cardinalità secondo voi va bene così?

1) Sul braccio che và da UTENTE a FEEDBACK imposto (0, n) perchè un utente acquirente può lasciare minimo 0 feedback (non ha ancora comprato nulla) e massimo n feedback (ha comprato più oggetti).

2) Sul braccio da FEEDBACK ad UTENTE imposto sempre (0, n) in quanto un utente venditore può aver ricevuto minimo 0 feedback (ancora non ha venduto alcun prodotto oppure il prodotto non è ancora stato ricevuto dall'acquirente che non ha ancora rilasciato il feedback) e massimo n (perchè potrebbe aver venduto n oggetti)

3) sul braccio da FEEDBACK ad INSERZIONE imposto (1,1) in quanto un feedback è riferito ad una ed una sola inserzione messa in vendita.

Per rendere più chiaro allego immagine, nello schema allegato la situazione è un po'più complessa perchè gestisco sia i feedback che gli acquirenti danno ai venditori mediante una relazione, sia il viceversa...ma alla fine il discorso non cambia.

http://www.siatec.net/andrea/uni/db/progettovisio.jpg

Per favore ditemi se va bene...ho pochissimo tempo :cry:

gugoXX
16-02-2008, 15:45
3) sul braccio da FEEDBACK ad INSERZIONE imposto (1,1) in quanto un feedback è riferito ad una ed una sola inserzione messa in vendita.

Per favore ditemi se va bene...ho pochissimo tempo :cry:

E' sbagliato.
Per motivi analoghi ai precedenti, potrebbe non esistere Feedback per un'inserzione... almeno fino a che non e' stata venduta.

D4rkAng3l
16-02-2008, 15:55
E' sbagliato.
Per motivi analoghi ai precedenti, potrebbe non esistere Feedback per un'inserzione... almeno fino a che non e' stata venduta.

mm forse mi sono espresso male, i dati verranno messi nella "tabella feedback" solamente dopo che l'utente ha ricevuto il pacco dal venditore e gli ha dato una valutazione e l'utente non potrà fare altri acquisti sul sistema finchè non metterà darà il feedback al venditore.

Te come lo faresti?

Grazie
Andrea

gugoXX
16-02-2008, 16:09
No, quella e' giusta, avevo scritto prima che pubblicassi il disegno.

Pero' non so bene per le 3 in alto.
Quando avevo studiato il la semantica del modello ER, per quanto riguarda le relazioni, la chiave primaria (che sia fisica, che sia logica poco importa) si poteva dedurre direttamente dalle entita' che vi insistevano.
Tu dovrai per forza mettere almeno il tempo nella chiave primaria (fisica o logica, non importa ripeto).
Non ve l'hanno fatta mai modellare l'entita' tempo?

Quando l'avevo studiata io era una tabella tratteggiata, che puntava a tutte le relazioni in cui il tempo serviva.
Tratteggiata perche' poteva essere creata veramente, oppure poteva essere alla fine usato semplicemente un campo di tipo DATA, il cui tipo e' presente in tutti i Database.
Nel tuo caso appunto commento, vendita e offerta, le cui PK dovrebbero contenere appunto il tempo in chiave.

Come dire, il "tempo" in quelle 3 tabelle e' ben diverso dal "tempo" della tabella inserzione, o della tabella Feedback, che li' sarebbero usati come attributo.(Istante di pubblicazione, Istante dell'inserzione, etc.)

gugoXX
16-02-2008, 16:35
A parte il tratteggio della tabella Tempo, intendo una cosa del genere

http://img.photobucket.com/albums/v314/gugogugo/ER001.jpg

Se noti la data ogni tanto va a finire sopra, ovvero tra i campi identificativi in questo modello (chiave), ogni tanto va a finire sotto, solo come attributo.
Da te, indipendentemente dalla soluzione grafica, l'ho visto sempre solo "sotto", ovvero tra gli attributi non identificativi.
Coem dire di nuovo, la DATA/ORA di un commento e' ben diversa dalla DATA/ORA di nascita dell'utente.

D4rkAng3l
16-02-2008, 16:36
quindi secondo te è giusto così?

gugoXX
16-02-2008, 16:39
Boh? Dipende da cosa vi hanno spiegato.
Ve l'hanno spiegata la differenza tra "Relazione identificativa" e "Relazione non identificativa"?
Ovvero, campo di una tabella che punta ad un altra (foreign key) e che partecipa anche alla chiave primaria della tabella stessa (Relazione identificativa)
oppure campo di una tabella che punta ad un altra (foreign key) ma che NON partecipa anche alla chiave primaria della tabella stessa (Relazione non identificativa) perche' e' solo un attributo?
(Come per esempio la mia inserizione nella tabella Messaggio. L'insezione non e' identificativa, perche' per identificare univocamente un messaggio e' sufficiente la terna (UtenteA, UtenteB, istante ))

D4rkAng3l
16-02-2008, 16:46
Boh? Dipende da cosa vi hanno spiegato.
Ve l'hanno spiegata la differenza tra "Relazione identificativa" e "Relazione non identificativa"?
Ovvero, campo di una tabella che punta ad un altra (foreign key) e che partecipa anche alla chiave primaria della tabella stessa (Relazione identificativa)
oppure campo di una tabella che punta ad un altra (foreign key) ma che NON partecipa anche alla chiave primaria della tabella stessa (Relazione non identificativa) perche' e' solo un attributo?
(Come per esempio la mia inserizione nella tabella Messaggio. L'insezione non e' identificativa, perche' per identificare univocamente un messaggio e' sufficiente la terna (UtenteA, UtenteB, istante ))

si le abbiamo viste ma sinceramente non mi và di stravolgere il lavoro che ho già fatto in quanto ho solo due giorni per tradurlo in schema relazionale, metterlo su MySql, inserire i dati, fare 20 query e produrre una relazione...quindi magari non è la soluzione migliore di tutte ma francamente adesso come adessomi basta che non sia clamorosamente sbagliata...già non ho la certezza di finire in tempo...se mi metto a fare modifiche strutturali sull'ER ho la certezza di non finire in tempo :cry:

gugoXX
16-02-2008, 16:54
Capisco.
A questo punto fai bene attenzione alle chiavi primarie delle tabelle e ai vincoli di unicita'.
Come dire, la tua tabella di relazione "Vende", puo' essere costruita come una tabella in cui la PK e' formata dalle PK delle entita' a cui punta (Utente, Inserzione)
mentre la tua tabella di relazione "Messaggio", NON puo' essere costruita come una tabella la cui PK e' l'insieme delle PK delle tabelle entita' a cui punta (Mittente, Destinatario, Inserzione) altrimenti vincoleresti un utente a mandare un solo messaggio per ogni inserzione.

D4rkAng3l
16-02-2008, 17:02
Capisco.
A questo punto fai bene attenzione alle chiavi primarie delle tabelle e ai vincoli di unicita'.
Come dire, la tua tabella di relazione "Vende", puo' essere costruita come una tabella in cui la PK e' formata dalle PK delle entita' a cui punta (Utente, Inserzione)
mentre la tua tabella di relazione "Messaggio", NON puo' essere costruita come una tabella la cui PK e' l'insieme delle PK delle tabelle entita' a cui punta (Mittente, Destinatario, Inserzione) altrimenti vincoleresti un utente a mandare un solo messaggio per ogni inserzione.

no lo sò, la tabella messaggio in fase di ristrutturazione avrà come chiave un campo id_messaggio e la cosa sarà motivata nella documentazione.

gugoXX
16-02-2008, 17:11
no lo sò, la tabella messaggio in fase di ristrutturazione avrà come chiave un campo id_messaggio e la cosa sarà motivata nella documentazione.

Ecco, io e' questa cosa della ristrutturazione che non capisco.
Il modello ER dovrebbe essere autoesplicativo. Il progettista di DB disegna il modello ER, poi lo passa ad un operatore (che potrebbe anche essere una macchina), che senza tanta intelligenza lo trasforma in istruzioni SQL per creare il Database.
Vabbe', se cosi' vi hanno insegnato fai pure... :rolleyes:

D4rkAng3l
16-02-2008, 17:20
Ecco, io e' questa cosa della ristrutturazione che non capisco.
Il modello ER dovrebbe essere autoesplicativo. Il progettista di DB disegna il modello ER, poi lo passa ad un operatore (che potrebbe anche essere una macchina), che senza tanta intelligenza lo trasforma in istruzioni SQL per creare il Database.
Vabbe', se cosi' vi hanno insegnato fai pure... :rolleyes:

Beh oddio, mo non vorrei sembrare superbo perchè sono un pivellino, però sull'Atzeni c'è tutto il capitolo 8 che è dedicato alla ristrutturazione di schemi ER e da quello che dice lo schema ER è solo una visione d'insieme di cosa contiene il DB e di come queste cose sono messe in relazione tra loro....poi prima di trasformare l'ER in tabelle bisogna anzitutto fare un'analisi del carico e del costo delle operazioni quindi ristrutturarlo in base alle operazioni che vengono eseguite con più frequenza per rendere il DB più performante e anche normalizzato...poi si passa al disegno dello schema relazionale...e quest'ultimo allora potrebbe essere passato ad un'operatore che potrebbe anche essere un software che lo trasforma in SQL...

gugoXX
16-02-2008, 17:24
Come vuoi.
Magari quello che hai fatto e' una prima fase, e magari vi hanno richiseto solo quella, ma prima o poi si deve passare allo schema ER rigoroso.

P.ES. Io prendo il mio ER, disegnato cosi' com'e' e lo passo all'automa che mi genera questo.
E va gia' bene cosi' senza altri passaggi. Se ho usato bene le PK, e le FK mancano solo i campi, ma la struttura e' funzionale.


CREATE TABLE Tempo (
Time DATE NOT NULL,
PRIMARY KEY (Time)
);


CREATE TABLE Inserzione (
PKInserzione INTEGER NOT NULL,
Scadenza DATE NULL,
PRIMARY KEY (PKInserzione),
FOREIGN KEY (Scadenza)
REFERENCES Tempo
);


CREATE TABLE Utente (
PKUtente INTEGER NOT NULL,
PRIMARY KEY (PKUtente)
);


CREATE TABLE Vendita (
PKUtente INTEGER NOT NULL,
PKInserzione INTEGER NOT NULL,
Time DATE NOT NULL,
PRIMARY KEY (PKUtente, PKInserzione, Time),
FOREIGN KEY (Time)
REFERENCES Tempo,
FOREIGN KEY (PKInserzione)
REFERENCES Inserzione,
FOREIGN KEY (PKUtente)
REFERENCES Utente
);


CREATE TABLE Vende (
PKUtente INTEGER NOT NULL,
PKInserzione INTEGER NOT NULL,
IstanteDiInserzione DATE NULL,
PRIMARY KEY (PKUtente, PKInserzione),
FOREIGN KEY (IstanteDiInserzione)
REFERENCES Tempo,
FOREIGN KEY (PKInserzione)
REFERENCES Inserzione,
FOREIGN KEY (PKUtente)
REFERENCES Utente
);


CREATE TABLE Offerta (
PKUtente INTEGER NOT NULL,
PKInserzione INTEGER NOT NULL,
Time DATE NOT NULL,
PRIMARY KEY (PKUtente, PKInserzione, Time),
FOREIGN KEY (Time)
REFERENCES Tempo,
FOREIGN KEY (PKInserzione)
REFERENCES Inserzione,
FOREIGN KEY (PKUtente)
REFERENCES Utente
);


CREATE TABLE Messaggio (
Mittente INTEGER NOT NULL,
Destinatario INTEGER NOT NULL,
Time DATE NOT NULL,
PKInserzione INTEGER NULL,
PRIMARY KEY (Mittente, Destinatario, Time),
FOREIGN KEY (PKInserzione)
REFERENCES Inserzione,
FOREIGN KEY (Time)
REFERENCES Tempo,
FOREIGN KEY (Destinatario)
REFERENCES Utente,
FOREIGN KEY (Mittente)
REFERENCES Utente
);


CREATE TABLE Commento (
PKUtente INTEGER NOT NULL,
PKInserzione INTEGER NOT NULL,
Time DATE NOT NULL,
PRIMARY KEY (PKUtente, PKInserzione, Time),
FOREIGN KEY (Time)
REFERENCES Tempo,
FOREIGN KEY (PKInserzione)
REFERENCES Inserzione,
FOREIGN KEY (PKUtente)
REFERENCES Utente
);

gugoXX
16-02-2008, 18:02
Una cosa pero' non ho capito.
Perche' dici che p.es la relazione "Feedback Acquirente" - "Inserzione" e' (1:1)
e non una (0:1)

Ovvero, se la risposta e' "Perche' penso di inserire il feedback in un secondo tempo, e quindi quando il feedback esistera' allora esistera' anche l'inserzione", allora perche' la relazione "Feedback Acquirente" - "Venditore" e' una (0:N) e non (1:N)
?

D4rkAng3l
16-02-2008, 18:13
Perchè nelle specifiche del sistema prevedo che il feedback è obbligatorio, l'acquirente una volta ricevuto il pacco e controllata la merce dovrà obbligatoriamente rilasciare il feedback al venditore.

gugoXX
16-02-2008, 18:21
Perchè nelle specifiche del sistema prevedo che il feedback è obbligatorio, l'acquirente una volta ricevuto il pacco e controllata la merce dovrà obbligatoriamente rilasciare il feedback al venditore.

OK, avevo capito, ma quello che non mi convince e' che tu possa scrivere (1:1) per quella relazione. Mi sembra piu' un vincolo applicativo, mi sembra una forzatura metterla sul modello del database.
Se lasci 1:1 significa che per qualsiasi inserzione DEVE esserci un feedback, sempre. Anche per quelle non ancora vendute.
Ma e' lana caprina, non penso che il professore si impunti.

D4rkAng3l
16-02-2008, 18:36
OK, avevo capito, ma quello che non mi convince e' che tu possa scrivere (1:1) per quella relazione. Mi sembra piu' un vincolo applicativo, mi sembra una forzatura metterla sul modello del database.
Se lasci 1:1 significa che per qualsiasi inserzione DEVE esserci un feedback, sempre. Anche per quelle non ancora vendute.
Ma e' lana caprina, non penso che il professore si impunti.

e se mettessi (0, 1) a significare che al massimo posso avere un feedback per un oggetto venduto?

gugoXX
16-02-2008, 18:44
Secondo me e' piu' giusto.

D4rkAng3l
16-02-2008, 19:28
Lo sò che a te questa cosa non garba molto però come ti ho detto non ho proprio il tempo materiale per cambiare l'impostazione del tutto...voglio solo verbalizzare qualsiasi cosa mi metta...

Allora sono in fase di passaggio da schema ER a schema relazionale normalizzato...le relazioni ternarie presenti nelmio ER nel disegno dello schema relazionale le devo lasciare come nell'ER, giusto? (ovviamente inserendo le chiavi)

Per le relazioni dei feedback la chiave sarà banalmente l'USER_ID dell'acquirente, del venditore e l'ID_OGGETTO dell'oggetto in questione.

Per i messaggi invece che posso mandarne più di uno come fare? Per te qual'è migliore tra queste due soluzioni:

1) Imposto semplicemente un ID_MESSAGGIO per ogni messaggio (usando l'auto increment), quindi ci sarà un numeretto che mi identifica ogni messaggio

2) Se usassi solo USER_ID del mittente, USER_ID del destinatario, ID_OGGETTO non basterebbe perchè potrei mandare più messaggi relativi ad un'oggetto...potrei inserire nella chiave anche la data e l'orario ma così avrei una chiave formata da 4 campi e non mi pare un gran che carino....

Per te qual'è la strategia più decente?

Grazie
Andrea

gugoXX
16-02-2008, 20:13
Intendiamoci, non e' che non mi piaccia il modello.
Secondo me hai trovato entita' e relazioni corrette.


1) Imposto semplicemente un ID_MESSAGGIO per ogni messaggio (usando l'auto increment), quindi ci sarà un numeretto che mi identifica ogni messaggio
2) Se usassi solo USER_ID del mittente, USER_ID del destinatario, ID_OGGETTO non basterebbe perchè potrei mandare più messaggi relativi ad un'oggetto...potrei inserire nella chiave anche la data e l'orario ma così avrei una chiave formata da 4 campi e non mi pare un gran che carino....

Propenderi per la prima, ma non perche' 4 campi in chiave nella seconda siano troppi, ma piuttosto perche' quei 4 non sono identificative.
2 sarebbero sufficienti:
Potrei modellare il fatto che ogni oggetto non possa ricevere piu' di un messaggio nello stesso istante. (Oggetto, Data)
Oppure sempre con 2:
Ogni utente puo' spedire un solo messaggio alla volta (Mittente, Data)
Oppure con 3:
Ogni utente puo' spedire un solo messaggio alla volta, riferito ad un singolo oggetto. Puo' pero' mandare piu' messaggi contemporaneamente, purche' riferiti ad oggetti diversi. (Mittente, Data, Oggetto)
Oppure sempre con 3:
Ogni utente puo' spedire un solo messaggio alla volta, per un altro utente. Puo' pero' mandare piu' messaggi contemporaneamente, purche' ad utenti diversi. (Mittente, Data, Destinatario)

Sono tutte modellazioni fisiche valide, ma con 4 anche a me sembra eccessivo se non errato.
L'errore starebbe nel considerare la variabilita' tra oggetto e destinatario, cosa che nel tuo modello non c'e'.
Per ciascun oggetto c'e' un solo destinatario. Metterli insieme in chiave in una qualsiasi tabella che non sia quella della loro relazione diretta (vende) non ha senso.
Non appena mi dici l'oggetto, so direttamente chi lo vende, non c'e' ambiguita'. Non c'e' necessita' di metterli entrambi insieme in una qualche chiave.

Quindi, se adotti la prima soluzione avrai meno cose da spiegare o giustificare...
Speriamo al professore non venga in mente di chiederti quindi piu' spiegazioni sulla chiave del feedback, per esempio.
Penso che tu stia facendo l'errore che se hai una relazione, allora il campo deve per forza essere in chiave nella tabella figlia.
Non e' cosi'. Esistono appunto le relazioni non identificative (le linee tratteggiate).

Tanto per essere onesti: Quando avevo passato l'esame di basi di dati, io personalmente non l'avevo capito.

D4rkAng3l
16-02-2008, 20:17
Intendiamoci, non e' che non mi piaccia il modello.
Secondo me hai trovato entita' e relazioni corrette.


Propenderi per la prima, ma non perche' 4 campi in chiave nella seconda siano troppi, ma piuttosto perche' quei 4 non sono identificative.
2 sarebbero sufficienti:
Potrei modellare il fatto che ogni oggetto non possa ricevere piu' di un messaggio nello stesso istante. (Oggetto, Data)
Oppure sempre con 2:
Ogni utente puo' spedire un solo messaggio alla volta (Mittente, Data)
Oppure con 3:
Ogni utente puo' spedire un solo messaggio alla volta, riferito ad un singolo oggetto. Puo' pero' mandare piu' messaggi contemporaneamente, purche' riferiti ad oggetti diversi. (Mittente, Data, Oggetto)
Oppure sempre con 3:
Ogni utente puo' spedire un solo messaggio alla volta, per un altro utente. Puo' pero' mandare piu' messaggi contemporaneamente, purche' ad utenti diversi. (Mittente, Data, Destinatario)

Sono tutte modellazioni fisiche valide, ma con 4 anche a me sembra eccessivo se non errato.
L'errore starebbe nel considerare la variabilita' tra oggetto e destinatario, cosa che nel tuo modello non c'e'.
Per ciascun oggetto c'e' un solo destinatario. Metterli insieme in chiave in una qualsiasi tabella che non sia quella della loro relazione diretta (vende) non ha senso.
Non appena mi dici l'oggetto, so direttamente chi lo vende, non c'e' ambiguita'. Non c'e' necessita' di metterli entrambi insieme in una qualche chiave.

Quindi, se adotti la prima soluzione avrai meno cose da spiegare o giustificare...
Speriamo al professore non venga in mente di chiederti quindi piu' spiegazioni sulla chiave del feedback, per esempio.
Penso che tu stia facendo l'errore che se hai una relazione, allora il campo deve per forza essere in chiave nella tabella figlia.
Non e' cosi'. Esistono appunto le relazioni non identificative (le linee tratteggiate).

Ok, ti ringrazio...e invece per quanto riguarda le relazioni di feedback? nel disegno dello schema relazionale le posso lasciare così come nell'ER visto che sono ternarie? (sistemando quella storia della cardinalità di cui si parlava prima).

gugoXX
16-02-2008, 20:40
Ok, ti ringrazio...e invece per quanto riguarda le relazioni di feedback? nel disegno dello schema relazionale le posso lasciare così come nell'ER visto che sono ternarie? (sistemando quella storia della cardinalità di cui si parlava prima).

Direi di si'.
Non penso che il professore analizzi a sufficienza il tuo modello tanto da chiederti perche' nel feedback hai messo in chiave sia oggetto che destinatario.

Penso che tu stia commettendo un altro errore, forse.
Quale e' la chiave primaria della tabella Vende?

D4rkAng3l
16-02-2008, 20:58
Direi di si'.
Non penso che il professore analizzi a sufficienza il tuo modello tanto da chiederti perche' nel feedback hai messo in chiave sia oggetto che destinatario.

Penso che tu stia commettendo un altro errore, forse.
Quale e' la chiave primaria della tabella Vende?

Intendi dire se per feedback devo riportare pari pari quello che ho nell'ER.

Cmq la chiave di VENDE per me è USER_ID di UTENTE e ID_OGGETTO di INSERZIONE.

Mi dovrebbe identificare in maniera univoca e mi dovrebbe collegare senza problemi le due entità in quanto ogni volta che un utente vende un oggetto questo viene inserito in INSERZIONE la cui chiave sarà un id numerico di tipo auto increment. E un utente non potrà mai vendere 2 volte lo stesso oggetto.

gugoXX
16-02-2008, 21:32
Intendi dire se per feedback devo riportare pari pari quello che ho nell'ER.

Cmq la chiave di VENDE per me è USER_ID di UTENTE e ID_OGGETTO di INSERZIONE.

Mi dovrebbe identificare in maniera univoca e mi dovrebbe collegare senza problemi le due entità in quanto ogni volta che un utente vende un oggetto questo viene inserito in INSERZIONE la cui chiave sarà un id numerico di tipo auto increment. E un utente non potrà mai vendere 2 volte lo stesso oggetto.

Hai fatto un pezzo di ragionamento. Hai impedito che nella tabella ci sia piu' di una volta la coppia UtenteA,Oggetto2
Ma quello che vorrei passarti e' che la chiave primaria di Vende, secondo me dovrebbe essere solamente Oggetto.
Un oggetto e' messo in relazione con un utente una volta sola, pertanto ogni Oggetto non dovrebbe comparire MAI piu' di una volta in quella tabella.
Ed e' questo il motivo per cui in fase di modellazione si potrebbe tranquillamente fondere questa tabella all'interno della tabella oggetto.
Perche' dovrebbero avere fisicamente la stessa chiave primaria.
La relazione verso l'utente ovviamente ci sarebbe, ma non identificativa.
L'utente non dovrebbe essere messo in chiave, pur avendo una chiave straniera verso la tabella degli utenti.
Sono riuscito a spiegarmi? Non sei d'accordo?

La vera schematizzazione, che se guardi ho sbagliato anche io nel veloce disegno che ho fatto, e' che la linea tra utente e vende dovrebbe essere tratteggiata.

Comunque direi che va bene per la feedback ternaria.
A questo punto lascia anche la Vende binaria altrimenti il professore potrebbe mangiare la foglia.

D4rkAng3l
17-02-2008, 10:41
Ciao,
rieccomi quà a rompere le scatole.
Visto che la relazione VENDE è una relazione di tipo UNO A MOLTI, dici che è meglio eliminarla ed inserire la chiave di UTENTE (USER_ID) dentro l'entità INSERZIONE, così eliminerei una tabella e cmq avrei il vincolo di integrità referenziale che punta da INSERZIONE ad UTENTE.

Invece l'altra cosa importante è la relazione VENDITA, altra relazione uno a molti. Tale relazione in pratica serve a contenere le vendite effettuate e lega un utente del sistema con il prodotto da lui acquistato.
Dal momento che la cardinalità minima dell'entità INSERZIONE che entra in gioco in questa relazione è 0 (in quanto su quel braccio la cardinalità è (0, 1)...credo di averlo dimenticato nell'ER postato) allora potrei anche mantenere una tabella VENDITA nello schema relazionale. che ne dici?

D4rkAng3l
17-02-2008, 11:42
mmm ancora un altro dubbio (ho quasi finito :D :mc: ).

Per le due relazioni feedback che voglio mantenere come relazioni...che chiavi metto? Avevo pensato che potrei impostare come chiave anche il solo ID_OGGETTO...secondo te potrebbe andare? (senza mettere in chiave l'ID dell'utente venditore e dell'acquirente...che magari metto come campi normali perchè credo che l'IDE_OGGETTO sia più che sufficiente ad identificarmi in maniera univoca una riga).

Grazie
Andrea

gugoXX
17-02-2008, 11:43
Ciao,
rieccomi quà a rompere le scatole.
Visto che la relazione VENDE è una relazione di tipo UNO A MOLTI, dici che è meglio eliminarla ed inserire la chiave di UTENTE (USER_ID) dentro l'entità INSERZIONE, così eliminerei una tabella e cmq avrei il vincolo di integrità referenziale che punta da INSERZIONE ad UTENTE.
Perfetto. Campo di una foreign key, che ovviamente non sara' in chiave nella tabella INSERZIONE. (relazione non identificativa).


Invece l'altra cosa importante è la relazione VENDITA, altra relazione uno a molti. Tale relazione in pratica serve a contenere le vendite effettuate e lega un utente del sistema con il prodotto da lui acquistato.
Dal momento che la cardinalità minima dell'entità INSERZIONE che entra in gioco in questa relazione è 0 (in quanto su quel braccio la cardinalità è (0, 1)...credo di averlo dimenticato nell'ER postato) allora potrei anche mantenere una tabella VENDITA nello schema relazionale. che ne dici?
Va bene.

VENDITA, con chiave (Oggetto, Acquirente) (Forse sarebbe meglio chiamarla ACQUISTI)
Attributi: data,...

Non e' necessario mettere il Venditore, perche', come gia' detto, e' univocamente definito dall'oggetto.

gugoXX
17-02-2008, 11:48
mmm ancora un altro dubbio (ho quasi finito :D :mc: ).

Per le due relazioni feedback che voglio mantenere come relazioni...che chiavi metto? Avevo pensato che potrei impostare come chiave anche il solo ID_OGGETTO...secondo te potrebbe andare? (senza mettere in chiave l'ID dell'utente venditore e dell'acquirente...che magari metto come campi normali perchè credo che l'IDE_OGGETTO sia più che sufficiente ad identificarmi in maniera univoca una riga).

Grazie
Andrea

Esatto. Se conti di modellare uno e un solo FEEDBack per ciascuna inserzione, allora ID_OGGETTO e' sufficiente, con relazione di integrita' verso la tabella inserzione.

La relazione verso l'acquirente non e' identificativa, non e' necessario metterla in chiave.

Anche qui, essendo il venditore univocamente definito dall'oggetto, sarebbe superfluo metterlo in uno schema normalizzato. Se lo metti non e' un errore (denormalizzazione parziale) ma non lo metterei appunto in chiave.

D4rkAng3l
17-02-2008, 11:52
Ok ti rignrazio troppo...

Ora manca solo l'ultima relazione da tadurre: SUBCAT.

Si tratta di una relazione ricorsiva tra l'entità CATEGORIA e se stessa. Praticamente dice quando una categoria è sottocategoria di un'altra.

E' di tipo uno a molti in quanto una categoria può avere minimo 0 sottocategorie e massimo n e viceversa una sottocategoria può avere una ed una sola sola categoria padre.

Adesso mi sorge un dubbio, passando allo schema relazionale è meglio mantenere una relazione SUBCAT che conterrà coppie, (ID_PADRE, ID_FIGLIA) che dicono chi è il padre di chi.

Oppure potrei fare un accorpamento PADRE-FIGLIA ed inserire un campo PADRE dentro CATEGORIA che dice qual'è il padre di quella categoria e se la categoria in questione non ha padre (in quanto categoria principale) allora avrà un NULL (che a mio avviso non è troppo carino).

Io tenderei a mantenere una relazione SUBCAT che mi contiene le varie coppie per evitare il fatto dei valori NULL...te che mi dici?

Poi dopo di questa cosa ho finito di tradurre lo schema ER in relazionale
Grazie

Andrea

gugoXX
17-02-2008, 12:09
Normalmente per casi come quello si usa una tabella sola.

Tassonomia:
ID_tassonomia, chiave
Descrizione, stringa
ID_tassonomia_padre, FK alla tabella stessa, non obbligatorio

E' il pattern che serve per modellare quello che in teoria dei grafi e' una FORESTA, ovvero un insieme di ALBERI.
I nodi radice di ciascun albero sarebbero per te le "MacroCategorie", che non hanno padre.
Ciascuno dei figli invece e' collegato al proprio padre, mediante il campo ID_tassonomia_padre.

Applicativamente occorrera' poi sviluppare delle QUERY ricorsive per navigare la foresta, ma quasi tutti i motori di Database seri hanno il supporto per le query ricorsive.
PS: Una foresta si puo' ridurre ad un albero unico, con un unico nodo padre.
Ma tale padre non avrebbe comunque un padre, pertanto resta lo stesso il vincolo di non obbligatorieta' della foreign key autoreferenziale.

Tale relazione, ovvero foreign key non referenziale e pure non obbligatorie, si modella nel grafico ER con una linea tratteggiata, e con un pallino vuoto vicino al campo di partenza (che sarebbe ID_TASSONOMIA_PADRE di questo esempio)

Ma poi basta, senno' Cionci dice il voto lo danno a me.

D4rkAng3l
17-02-2008, 12:16
Normalmente per casi come quello si usa una tabella sola.

Tassonomia:
ID_tassonomia, chiave
Descrizione, stringa
ID_tassonomia_padre, FK alla tabella stessa, non obbligatorio

E' il pattern che serve per modellare quello che in teoria dei grafi e' una FORESTA, ovvero un insieme di ALBERI.
I nodi radice di ciascun albero sarebbero per te le "MacroCategorie", che non hanno padre.
Ciascuno dei figli invece e' collegato al proprio padre, mediante il campo ID_tassonomia_padre.

Applicativamente occorrera' poi sviluppare delle QUERY ricorsive per navigare la foresta, ma quasi tutti i motori di Database seri hanno il supporto per le query ricorsive.
PS: Una foresta si puo' ridurre ad un albero unico, con un unico nodo padre.
Ma tale padre non avrebbe comunque un padre, pertanto resta lo stesso il vincolo di non obbligatorieta' della foreign key autoreferenziale.

Tale relazione, ovvero foreign key non referenziale e pure non obbligatorie, si modella nel grafico ER con una linea tratteggiata, e con un pallino vuoto vicino al campo di partenza (che sarebbe ID_TASSONOMIA_PADRE di questo esempio)

Ma poi basta, senno' Cionci dice il voto lo danno a me.

mmm la mia proff ODIA A MORTE le query ricorsive...ha minacciato bocciatura se ne vede anche una sola...che fare?

gugoXX
17-02-2008, 12:39
mmm la mia proff ODIA A MORTE le query ricorsive...ha minacciato bocciatura se ne vede anche una sola...che fare?

Fallo come l'hai fatto tu.
Non sembra ricorsiva, ma lo e' lo stesso. Ma magari non se ne accorge.

Sia nella singola tabella autoreferenziante che nel tuo disegno a 2 tabelle, per risolvere una domanda come:
"DATO un nodo della foresta, trovare quale e' il suo ANCESTOR"
che da te sarebbe
"Dato una qualsiasi categoria, trovare a quale MACRO Categoria appartiene"

Occorre comunque fare una query ricorsiva.
E non penso neppure che le abbiate fatte, perche' sono delle brutte bestie.

D4rkAng3l
17-02-2008, 12:43
Fallo come l'hai fatto tu.
Non sembra ricorsiva, ma lo e' lo stesso. Ma magari non se ne accorge.

Sia nella singola tabella autoreferenziante che nel tuo disegno a 2 tabelle, per risolvere una domanda come:
"DATO un nodo della foresta, trovare quale e' il suo ANCESTOR"
che da te sarebbe
"Dato una qualsiasi categoria, trovare a quale MACRO Categoria appartiene"

Occorre comunque fare una query ricorsiva.
E non penso neppure che le abbiate fatte, perche' sono delle brutte bestie.

ma se invece lo facessi usando una tabella sola come hai detto te e poi per le query invece di fare query ricorsive usassi la strategia degli alias per "duplicare" la tabella con un altro nome?

gugoXX
17-02-2008, 12:51
ma se invece lo facessi usando una tabella sola come hai detto te e poi per le query invece di fare query ricorsive usassi la strategia degli alias per "duplicare" la tabella con un altro nome?

Ho intuito cosa stai dicendo.
Stai proponendo di fare delle query autoreferenzianti, nelle quali piazzi piu' volte la stessa tabella in join con se stessa.
Penso che non possa farlo "a priori" nel tuo modello, perche' dovresti sapere quante volte piazzare la tabella in JOIN con se stessa, che dipende dal livello di profondita' di ciascun nodo.
Poiche' dipende dal livello di profondita', essendo il livello variabile per ciascun nodo, secondo me non riesci a fare un'unica query generale che possa funzionare a priori indipendentemente dal nodo che cerchi.
Forse con delle OUTER JOIN, ma mi sa che non viene molto bella da farsi e da leggersi.

Tutto dipende da cosa devi farci con quella tabella.
A parte scriverci dentro, come la leggi? Cosa viene pubblicato di quella tabella?
Se il tuo "sito" mostra una navigazione ad un livello solo, ovvero fa vedere di volta in volta tutti gli oggetti venduti che appartengono alla categoria corrente, e ti propone la navigazione verso il padre (se esiste) e verso uno qualsiasi dei suoi figli diretti (se esistono), allora non ti servono le query ricorsive. Te la cavi con 2 query normali.
In tal caso una tabella come la soluzione da me proposta, oppure 2 tabelle come la tua, vanno entrambe bene.

D4rkAng3l
17-02-2008, 13:01
mmm mi sà che ho capito cosa intendi...praticamente te stai dicendo che facendo query di questo tipo usando gli alias potrei fare una query del tipo: "Dimmi tutte le categorie figlie della categoria "FOTOGRAFIA"".

Però usando questa strategia potrei dire quali sono le figlie dirette e non le figlie delle figlie, etcetc....intendi questo?

mmm e se mi tengo la relazione SUBCAT dici che è una porcata?

Grazie
Andrea

gugoXX
17-02-2008, 13:05
mmm mi sà che ho capito cosa intendi...praticamente te stai dicendo che facendo query di questo tipo usando gli alias potrei fare una query del tipo: "Dimmi tutte le categorie figlie della categoria "FOTOGRAFIA"".

Il problema e' esattamente questo, ma sto dicendo che usando gli "alias" e non le query ricorsive, a quella domanda non riesci a rispondere facilmente, se non addiruttura impossibile.
ES: Se sul tuo sito volessi mostrare tutte gli oggetti venduti da una categoria e conteporaneamente anche da tutte le sue categorie figlie, nipoti, etc... allora dico che senza le query ricorsive non ne esci. Prova a chiedere alla tua Professoressa, alle quali non piacciono, come risolverebbe questo problema, che modello e che query farebbe.
Se la risposta fosse "Lancio una query che mi da tutti i figli, e per ciascuno di questi rilancio poi la stessa query", allora e' un altro modo per fare "male" una query ricorsiva


Però usando questa strategia potrei dire quali sono le figlie dirette e non le figlie delle figlie, etcetc....intendi questo?

Esatto.


mmm e se mi tengo la relazione SUBCAT dici che è una porcata?


No, non e' necessaria ma non e' una porcata.

D4rkAng3l
17-02-2008, 13:11
vabbuò...vado a pappare e spero che il pranzo mi porti anche saggezza :D Ti rin grazio tantissimo ;-)

D4rkAng3l
17-02-2008, 15:47
Quindi ricapitolando te accorperesti la relazione SUBCAT dentro CATEGORIA e metteresti il campo Padre dentro CATEGORIA così da sapere per ogni record (quindi per ogni categoria) chi è la categoria padre di quel record per qvere una cosa del genere


ID_CATEGORIA, NOME_CAT, DESCRIZIONE PADRE

001, HOBBY, blablabla, NULL
006, FOTOGRAFIA, blablabla, 001

Intendevi questo?

Grazie
Andrea

gugoXX
17-02-2008, 16:45
Quindi ricapitolando te accorperesti la relazione SUBCAT dentro CATEGORIA e metteresti il campo Padre dentro CATEGORIA così da sapere per ogni record (quindi per ogni categoria) chi è la categoria padre di quel record per qvere una cosa del genere


ID_CATEGORIA, NOME_CAT, DESCRIZIONE PADRE

001, HOBBY, blablabla, NULL
006, FOTOGRAFIA, blablabla, 001

Intendevi questo?

Grazie
Andrea

Beh, senza la descrizione padre in tabella pero', che non e' normalizzata.

001, Hobby, null
002, Fotografia, 001
003, Bricolage, 001
004, Informatica, null
005, Hardware,004
006, Software,004
007, Canon, 002
008, Konika, 002
etc.

Puoi sapere subito tutto dei figli diretti di 002
SELECT * FROM tabella WHERE padre=002


E puoi sapere tutto del padre
SELECT * FROM tabella
WHERE ID = (SELECT padre FROM tabella WHERE ID=002)

oppure se non vi hanno spiegato le inner query lo fai con la INNER JOIN

SELECT tab1.*
FROM tabella AS tab1 JOIN tabella AS tab2
ON (tab1.ID=tab2.padre)
WHERE tab2.ID=002

D4rkAng3l
17-02-2008, 16:56
mmm no Descrizione è solo un campo di Categoria e non è legato al Padre (forse mi son mangiato una virgola).

Nel senso se il titolo della categoria è: "Fotografia" la sua descrizione sarà un campo testuale che ne sò qualcosa del tipo: "Inserzioni relative alla fotografia: macchine fotografiche, flash e attrezzatura fotografica di vario genere".

Ho appena finito di tradurre lo schema relazionale.
Dici che è decente qualcosa del genere? (Le chiavi sono con la pallina rossa, i campi con le palline nere). Dove le relazioni sono state eliminate aggiungendo un campo ad un'entità che punta ad un'altra entità ho messo la freccia. Dove non le ho eliminate ho lasciato la relazione con relative cardinalità che di fatto nello schema relazionale è una tabella.

http://www.siatec.net/andrea/uni/db/fisico.jpg

Grazie
Andrea

gugoXX
17-02-2008, 17:05
Va bene.
Solo 2 cose:
La chiave di Offerta e' sbagliata.
E secondo me dovresti mettere la freccia autoreferenziante della tabella Categoria, nel senso che il campo "padre" deve puntare al campo "Id_categoria" della tabella stessa, ma se dici che si arrabbia...

D4rkAng3l
17-02-2008, 17:26
Va bene.
Solo 2 cose:
La chiave di Offerta e' sbagliata.
E secondo me dovresti mettere la freccia autoreferenziante della tabella Categoria, nel senso che il campo "padre" deve puntare al campo "Id_categoria" della tabella stessa, ma se dici che si arrabbia...

Ok, freccia aggiunta...

Che chiave metteresti per OFFERTA? Ora che lo riguardo credo che basti ID_OGGETTO e VALORE_OFFERTA se assumiamo che durante un'asta se un utente offre 5 €, la successiva offerta per quell'oggetto deve per forza di cose essere maggiore della precedente. Te faresti così o in altro modo?

Grazie
Andrea

gugoXX
17-02-2008, 17:39
Ok, freccia aggiunta...

Che chiave metteresti per OFFERTA? Ora che lo riguardo credo che basti ID_OGGETTO e VALORE_OFFERTA se assumiamo che durante un'asta se un utente offre 5 €, la successiva offerta per quell'oggetto deve per forza di cose essere maggiore della precedente. Te faresti così o in altro modo?

Grazie
Andrea

No, bruttino.
Metti anche per quello un ID_Offerta.
Oppure se riesci a spiegarla bene in realta' io metterei ID_Oggetto, ID_Offerta, dove ID_Offerta e' un intero che parte da 0 per ogni oggetto, e sale ogni volta che qualcuno piazza un offerta per quell'oggetto.
Si chiama "Chiave Surrogata", ovvero l'unione di una chiave vera con un contatore ad hoc per la tabella.
Non so se si chiama chiave surrogata anche quando c'e' il contatore da solo. In pratica in quel caso si dice solo "Contatore".

D4rkAng3l
17-02-2008, 17:41
No, bruttino.
Metti anche per quello un ID_Offerta.
Oppure se riesci a spiegarla bene in realta' io metterei ID_Oggetto, ID_Offerta, dove ID_Offerta e' un intero che parte da 0 per ogni oggetto, e sale ogni volta che qualcuno piazza un offerta per quell'oggetto.
Si chiama "Chiave Surrogata", ovvero l'unione di una chiave vera con un contatore ad hoc per la tabella.
Non so se si chiama chiave surrogata anche quando c'e' il contatore da solo. In pratica in quel caso si dice solo "Contatore".

mmm mi sà che metto un id_offerta univoco per non sconvolgere troppo la proff con cose che non abbiamo trattato al corso

D4rkAng3l
18-02-2008, 08:55
ok...ora devo iniziare a tradurre tutto in SQL (speriamo bene perchè l'ho usato poche volte a livello pratico...)

Quindi ogni relazione del modello relazionale è una tabella.

Dato il precedente schema avrò una cosa del genere per fare un esempio:

UTENTE(User_Id, Nome, Cognome, Data_Nascita, Indirizzo).

INSERZIONE(Id_Oggetto, Titoo, Descrizione, Costo_Di_Partenza, Data_Scadenza, Compralo_Subito, Id_Venditore, Id_Categoria).

Dove i campi Id_Venditore ed Id_Categoria di INSERZIONE sono in rosso perchè saranno referenziati dalla tabella UTENTE....giusto? (tramite foreign key(campo) references UTENTE(campo) ).

E' corretto?

Grazie
Andrea