-

Esercizio sql

#1
Ciao a tutti. Ho un dubbio che non so se possa essere risolto in maniera ''elementare'' o meno. Facendola breve, ho creato la tabella "persona" e la tabella "amico" in questo modo (metto solo le chiavi)
Codice:
PERSONA                    AMICO

id                        id1
                          id2

pk(id)                   pk(id1,id2)

Dove id1 e id2 sono chiavi esterne di persona(id). La relazione dovrebbe essere simmetrica, quindi la chiave (id1,id2) e la chiave (id2,id1) dovrebero far riferimento alla stessa riga. Come posso fare per rendere la relazione simmetrica? Grazie
 
#3
Se in AMICO immagino che gli id PERSONA li memorizzi in due colonne differenti ti basta una clausola WHERE.
SQL:
SELECT * FROM AMICO
WHERE COLONNA1 = 'id1' OR COLONNA2 = 'id1'
No ma intendo, è possibile creare dei vincoli all'interno della tabella per far si che questo controllo venga creato in automatico? Con le interrogazioni saprei come fare.
Mi spiego meglio. Oltre alla tabella AMICO c'è anche la tabella PIACE, la quale comprende sempre id1 e id2 come chiavi primaria ma non è simmetrica, quindi effettivamente le coppie (id1,id2) e (id2,id1) fanno riferimento a due record distinti, cosa che nella tabella AMICO non è vera perchè si tratta di relazione simmetrica. Ora, le due relazioni sono una simmetrica (AMICO) e una asimmetrica(PIACE) e la mia domanda è, a livello di tabelle, sono entrambe uguali?
Spero di essermi spiegato. Grazie intento!
 
#4
Ti riesco a seguire a tratti. Che intendi per tabelle uguali? Se tu le interroghi per azioni differenti è ovvio che magari possano servirti entrambe anche se memorizzano quasi gli stessi dati (magari puoi migliorarla progettando la base di dati in modo diverso). Se tu la tabella AMICO la usi per tenere conto delle amicizie di una persona mentre PIACE per tener conto dei "mi piace" essendo relazioni lo stesso 1 ad 1 è ovvio che si creano associazioni identiche in entrambe le tabelle.
Spero di essere stato chiaro e aver in parte capito quello che intendi :D
 
Mi Piace: 891

1nd33d

Utente Attivo
652
275
Hardware Utente
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
Hard Disk
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
Scheda Video
XFX RX480 GTR Black Edition
Scheda Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
Alimentatore
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
Sistema Operativo
Windows 10 64bit - Linux Mint 18
#5
La relazione dovrebbe essere simmetrica, quindi la chiave (id1,id2) e la chiave (id2,id1) dovrebero far riferimento alla stessa riga. Come posso fare per rendere la relazione simmetrica? Grazie
Se ho ben capito, tu vuoi che, nel caso in cui nella tabella ci sia la chiave (id1, id2), non possa essere presente anche la chiave (id2, id1) e viceversa.
In tal caso penso che dovresti usare un trigger.
 
Mi Piace: 891
#6
Se tu la tabella AMICO la usi per tenere conto delle amicizie di una persona mentre PIACE per tener conto dei "mi piace" essendo relazioni lo stesso 1 ad 1 è ovvio che si creano associazioni identiche in entrambe le tabelle.
Spero di essere stato chiaro e aver in parte capito quello che intendi :D
Ok quindi le tabelle sono uguali poichè contengono gli stessi dati e poi io con le interrogazioni tiro fuori quello che mi serve, mi pare di avere capito giusto, no?

Se ho ben capito, tu vuoi che, nel caso in cui nella tabella ci sia la chiave (id1, id2), non possa essere presente anche la chiave (id2, id1) e viceversa.
In tal caso penso che dovresti usare un trigger.
Esatto, questa potrebbe essere la soluzione! Mi proverò a informare meglio comunque visto che i trigger ancora non li abbiamo fatti penso che basti eliminare i doppioni tramite interrogazioni. Comunque grazie, eventualmente scriverò qui sotto se dovessi avere bisogno di aiuto sui trigger :ok:
 
Mi Piace: Eduadie
#7
Ok quindi le tabelle sono uguali poichè contengono gli stessi dati e poi io con le interrogazioni tiro fuori quello che mi serve, mi pare di avere capito giusto, no?
Esattamente. Ovviamente se tu non vuoi creare stesse righe in una tabella puoi intervenire o come ti è stato suggerito con i trigger (controllando quindi con l'SQL direttamente) altrimenti a seconda del linguaggio che usi puoi implementare controlli lato codice.
 
#8
Mi vengono in mente 4 soluzioni:
- TRIGGER: come detto da altri utenti qui sopra. Lo svantaggio di questa soluzione è che il trigger scatta ogni volta che provi a fare una INSERT e dovendo controllare se sulla tabelle esiste già una relazione "simile" deve pure fare una query. In uno scenario critico per le performance potrebbe essere un problema.
- CONSTRAINT: stesso problema dei TRIGGER. Inoltre quando il constraint fallisce lancia un errore che poi deve essere gestito applicativamente. Userei questa soluzione in combinazione solo con la soluzione successiva.
- GESTIONE LATO SOFTWARE: gestisci questa tematica lato software, nella pratica però finisce per fare sempre quello che fa il TRIGGER, ovvero con una query controlli e poi decidi cosa fare.
- ACCETTARE I DUPLICATI: io valuterei attentamente questa soluzione perché la seguente query pur sintatticamente e funzionalmente corretta non è efficiente sui grandi numeri.

SQL:
SELECT * FROM AMICO
WHERE COLONNA1 = 'id1' OR COLONNA2 = 'id1'
Le query con con un OR tendezialmente non lo sono.
Ovviamente questa soluzione ha senso solo se la tabella AMICO ha solamente i 2 campi chiave. Se ci fossero anche altri campi da duplicare, diventerebbe insostenibile e poco mantenibile.

Sulle prime 3 soluzioni aggiungo un ulteriore consiglio: se proprio vuoi mantenere una sola relazione, dati una regola su quale tenere. Per esempio: salva solo la relazione con id1 < id2. In questo modo, se dovessi verificare se 2 persone sono amiche invece di scrivere:

SQL:
SELECT * FROM AMICO
WHERE (COLONNA1 = 'id1' AND COLONNA2 = 'id2') OR
(COLONNA1 = 'id2' AND COLONNA2 = 'id1')
potresti farlo molto più semplicemente con:

SQL:
SELECT * FROM AMICO
WHERE COLONNA1 = 'id1' AND COLONNA2 = 'id2'
 

Discussioni Simili


Entra

Guarda il video live di tomshardwareita su www.twitch.tv