2010-06-09 6 views
13

Ho un DB MySQL in cui memorizzo i dati relativi a ciascun utente.Tabella amici MySQL

Vorrei aggiungere un elenco di amici per ciascun utente. Devo creare una tabella di amici per ogni utente nel DB o c'è un modo migliore?

+2

Le amicizie sono bidirezionali o unidirezionali? Se Pete è amica di Maria, significa sempre che Maria è anche amica di Pete? –

+0

Si noti inoltre che il nome di ciò che si desidera è "tabella di intersezione" o forse anche "tabella di ricerca". Se hai familiarità con i concetti di database, è una tabella molti a molti, poiché un utente può avere molti amici e potrebbe essere molti amici con altre persone. Si noti inoltre che è possibile per un utente avere un amico che non è un amico, usando questo stile. Ci sono anche altri modi, ma questo è il più semplice da implementare. Forse un po 'di più sulla tua logica di business amichevole sarebbe d'aiuto? @Juha Syrjälä mi ha battuto per questo! – jcolebrand

+0

Gli amici sono unidirezionali e devono già esistere nel DB. È solo un elenco di promemoria di persone che conosci. – asmo

risposta

9

Supponendo che tutti i tuoi amici si trovino anche nella tabella utente, avrai bisogno di una tabella amici che definisce una semplice relazione uno-a-molti - collegando la tabella utenti a se stessa. Così

User Table 
UserID int identity not null 
[other attribute fields] 

Friends Table 
UserIDLink1 int 
UserIDLink2 int 
[other attribute field] 

Dove sia UserIDLink1 e UserIDLink2 sono le chiavi esterne sul tavolo Utenti.

Così, per esempio se ho tre utenti

1 Joe 
2 Bill 
3 Jane 

e Joe e Jane sono amici allora gli Amici tavolo conterrebbero una sola riga

1 3 

È possibile che questo assume implicitamente che se A è un amico di B allora B è amico di A - se questo non è il caso probabilmente vorrai rinominare UserIDLink1 e UserIDLink2 a UserID e FriendID o simili - nel qual caso avrai anche il doppio dei record.

anche per la configurazione bi-direzionale (A è un amico di B se B è un amico di A) è necessario impostare gli indici della tabella Friends for (UserIDLink1, UserIDLink2) e (UserIDLink2, UserIDLink1) per garantire l'accesso è sempre efficiente se cercassimo amici di joe o amici di jane (se non hai impostato il secondo indice, la prima query sarebbe stata una ricerca di indice efficiente ma la seconda richiederebbe una scansione completa della tabella).

Se i collegamenti non sono stati bidirezionale questo non sarebbe necessario per scoprire chi gli amici di A sono, ma si sarebbe probabilmente ancora più bisogno come è probabile che anche bisogno di scoprire chi B è un amico di.

+1

Mi chiedo, come si formula la query di join con due chiavi esterne (userIDLink1 e userIDLink2) che puntano alla stessa chiave primaria? – koceeng

-1

Creare una singola tabella per tutti gli amici e dare ogni amico un UserSID che è uguale alla loro chiave

0

rispettivi utenti Crea una tabella che contiene tutti gli amici Ogni riga della tabella contiene l'ID dell'utente e l'id del loro amico

+0

Quindi per ogni amico di ogni utente, aggiungo una riga in una tabella a 2 colonne (Utente, Amico). Ad esempio, se ho 200 utenti con 10 amici ciascuno, la tabella "Amici" dovrebbe contenere 2000 righe (10 per utente). Ho capito bene? – asmo

+1

@asmo è corretto, ma con una tabella altamente ottimizzata per indice, come si può avere in questo caso, non si dovrebbe avere paura delle tabelle con oltre un milione di righe, non sarà un problema. – Cruachan

7

Assumendo che il tavolo USER ha una chiave primaria chiamata id o qualcosa di simile, utilizzare la seguente tabella:

DROP TABLE IF EXISTS `friends`; 
CREATE TABLE `friends` (
    `user_id` int(10) unsigned NOT NULL, 
    `friend_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`user_id`,`friend_id`), 
    KEY `FK_FRIENDS_2` (`friend_id`), 
    CONSTRAINT `FK_FRIENDS_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), 
    CONSTRAINT `FK_FRIENDS_2` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Questo setu p sostiene che Peter è un amico di Maria, ma Mary non pensa a Peter così. Ma i dati esistono per dedurre che Peter è un conoscente di Mary ...

La chiave primaria essendo entrambe le colonne ferma anche i duplicati.

+0

Mi manca l'assegnazione di 'FK_FRIENDS_1' lì? – jcolebrand

+0

Più pulito con user_id e friend_id – rigobcastro

1

Stai cercando tabella di join M-to-N o many-to-many.

tabella utenti:

USER_ID integer primary key, 
NAME  varchar 

Amicizie Tabella

USER_ID integer not null, 
FRIEND_ID integer not null, 

Sia USER_ID e FRIEND_ID sono chiavi esterne che fanno riferimento tabella Users (Users.user_id).

Se l'utente 123 è amico dell'utente 921. Aggiungi riga (123, 921) alla tabella Amiche.

+0

Stai visualizzando solo 2 tabelle? Non è abbastanza uno-a-molti per questo? – Notflip