2010-06-09 9 views
13

Ich habe eine MySQL DB, in der ich Daten über jeden Benutzer speichern.MySQL Freunde Tabelle

Ich möchte eine Liste von Freunden für jeden Benutzer hinzufügen. Soll ich für jeden Benutzer in der Datenbank eine Freundesliste erstellen oder gibt es einen besseren Weg?

+2

Sind Freundschaften bidirektional oder unidirektional? Wenn Pete mit Mary befreundet ist, bedeutet das immer, dass Mary auch eine Freundin von Pete ist? –

+0

Beachten Sie auch, dass der Name, was Sie möchten, "Schnittstellentabelle" oder vielleicht auch "Nachschlagetabelle" ist. Wenn Sie mit Datenbankkonzepten vertraut sind, ist es ein Tisch für viele zu viele, da ein Benutzer viele Freunde haben kann und viele Freunde mit anderen Leuten sind. Beachten Sie auch, dass es für einen Benutzer möglich ist, einen Freund zu haben, der kein Freund ist und diesen Stil verwendet. Es gibt auch andere Möglichkeiten, aber dies ist am einfachsten zu implementieren. Vielleicht hilft dir ein bisschen mehr über deine Geschäftslogik für Freunde? @Juha Syrjälä hat mich dazu geschlagen! – jcolebrand

+0

Freunde sind unidirektional und müssen bereits in der DB vorhanden sein. Es ist nur eine Erinnerungsliste von Leuten, die du kennst. – asmo

Antwort

9

Angenommen, alle Ihre Freunde sind auch in der Benutzertabelle, benötigen Sie eine Freundes-Tabelle, die eine einfache Eins-zu-Viele-Beziehung definiert - indem Sie die Benutzertabelle mit sich selbst verknüpfen. So

Wobei sowohl UserIDLink1 und UserIDLink2 Fremdschlüssel in der Tabelle Benutzer sind.

So zum Beispiel, wenn ich drei Benutzer

1 Joe 
2 Bill 
3 Jane 

und Joe und Jane sind Freunde dann die Freunde Tabelle eine einzelne Zeile

1 3 

Die oben nimmt implizit enthalten würde, dass, wenn A a Freund von B dann B ist ein Freund von A - wenn dies nicht der Fall ist, möchtest du UserIDLink1 und UserIDLink2 wahrscheinlich in UserID und FriendID oder ähnliches umbenennen - in diesem Fall hättest du die Datensätze ebenfalls verdoppeln können.

Auch für die bidirektionale Konfiguration (A ist ein Freund von B, wenn B ein Freund von A ist) sollten Sie Indizes für die Friends-Tabelle für (UserIDLink1, UserIDLink2) und (UserIDLink2, UserIDLink1) einrichten, um den Zugriff zu gewährleisten ist immer effizient, wenn wir entweder nach Freunden von Joe oder Freunden von Jane suchen (wenn Sie den zweiten Index nicht eingerichtet hätten, wäre die erste Abfrage eine effiziente Indexsuche, die zweite würde jedoch einen vollständigen Tabellenscan erfordern).

Wenn Ihre Links nicht bidirektional wären, wäre dies nicht notwendig, um herauszufinden, wer A's Freunde sind, aber Sie würden wahrscheinlich immer noch die meisten benötigen, da Sie wahrscheinlich auch herausfinden müssen, mit wem B befreundet ist.

+1

Ich frage mich, wie Sie eine Join-Abfrage mit zwei Fremdschlüsseln (userIDLink1 und userIDLink2), die auf denselben Primärschlüssel zeigen, formulieren? – koceeng

-1

eine einzelne Tabelle erstellen die Freunde für alle und jeden Freund einen UserSid geben, die

0

Erstellen Sie eine Tabelle mit ihren jeweiligen Benutzer Schlüssel gleich ist, die alle Freunde Jede Zeile in der Tabelle enthält die ID des Benutzers enthalten und die ID ihres Freundes

+0

Also für jeden Freund von jedem Benutzer, ich füge eine Zeile in einer 2-Spalte-Tabelle (Benutzer, Freund). Zum Beispiel, wenn ich 200 Benutzer mit jeweils 10 Freunden habe, sollte die Tabelle "Freunde" 2000 Zeilen haben (10 pro Benutzer). Verstehe ich richtig? – asmo

+1

@asmo das ist richtig, aber mit einer hoch index-optimierten Tabelle wie Sie in diesem Fall haben Sie keine Angst vor Tabellen mit mehr als einer Million Zeilen - das wird kein Problem sein. – Cruachan

7

Angenommen, Ihre USER Tabelle hat einen Primärschlüssel id oder etwas ähnliches genannt, verwenden Sie die folgende Tabelle:

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; 

Diese setu p unterstützt, dass Peter ein Freund Marias ist, aber Maria denkt nicht so an Peter. Aber die Daten existieren, um zu folgern, dass Peter ein Bekannter für Mary ist ...

Der Primärschlüssel, der beide Spalten ist, stoppt auch Duplikate.

+0

Fehle ich dort die Zuordnung von 'FK_FRIENDS_1'? – jcolebrand

+0

Mehr sauber mit user_id und friend_id – rigobcastro

1

Sie suchen eine M-to-N- oder Viele-zu-Viele-Join-Tabelle.

Tabelle Benutzer:

USER_ID integer primary key, 
NAME  varchar 

Tabelle Friendships

USER_ID integer not null, 
FRIEND_ID integer not null, 

Sowohl USER_ID und FRIEND_ID sind Fremdschlüssel, die Benutzer-Tabelle (Users.user_id) verweisen.

Wenn Benutzer 123 Freund von Benutzer 921 ist. Fügen Sie Zeile (123, 921) zu Friendships-Tabelle hinzu.

+0

Sie sehen nur 2 Tabellen? Ist das nicht eins-zu-viele genug? – Notflip