2010-06-09 6 views
13

J'ai une base de données MySQL dans laquelle je stocke des données sur chaque utilisateur.Table des amis MySQL

Je voudrais ajouter une liste d'amis pour chaque utilisateur. Dois-je créer une table d'amis pour chaque utilisateur dans la base de données ou existe-t-il un meilleur moyen?

+2

Les amitiés sont-elles bidirectionnelles ou unidirectionnelles? Si Pete est l'ami de Marie, cela signifie-t-il toujours que Marie est aussi amie de Pete? –

+0

Notez également que le nom de ce que vous souhaitez est "table d'intersection" ou peut-être aussi "table de recherche". Si vous êtes familier avec les concepts de base de données, il s'agit d'une table de plusieurs à plusieurs, car un utilisateur peut avoir beaucoup d'amis et peut avoir beaucoup d'amis avec d'autres personnes. Notez également qu'il est possible pour un utilisateur d'avoir un ami qui n'est pas un ami, en utilisant ce style. Il y a d'autres moyens, mais c'est le plus simple à mettre en œuvre. Peut-être qu'un peu plus sur votre logique d'entreprise amicale aiderait? @Juha Syrjälä m'a battu à ça! – jcolebrand

+0

Les amis sont unidirectionnels et doivent déjà exister dans la base de données. C'est juste une liste de rappel de personnes que vous connaissez. – asmo

Répondre

9

En supposant que tous vos amis sont également dans la table utilisateur, vous aurez besoin d'une table d'amis qui définit une simple relation un-à-plusieurs - reliant la table des utilisateurs à elle-même. Donc

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

Friends Table 
UserIDLink1 int 
UserIDLink2 int 
[other attribute field] 

Lorsque UserIDLink1 et UserIDLink2 sont des clés étrangères dans la table Utilisateurs.

Ainsi, par exemple, si j'ai trois utilisateurs

1 Joe 
2 Bill 
3 Jane 

et Joe et Jane sont amis alors la table d'amis contiendraient une seule rangée

1 3 

Ce qui précède suppose implicitement que si A est un ami de B puis B est un ami de A - si ce n'est pas le cas, vous voudrez probablement renommer UserIDLink1 et UserIDLink2 en UserID et FriendID ou similaire - auquel cas vous auriez jusqu'à doubler les enregistrements.

Aussi pour la configuration bidirectionnelle (A est un ami de B si B est un ami de A), vous devez configurer des index sur la table des amis pour (UserIDLink1, UserIDLink2) et (UserIDLink2, UserIDLink1) pour assurer l'accès est toujours efficace si nous cherchions soit des amis de joe ou des amis de jane (si vous n'aviez pas configuré le second index, la première requête serait une recherche d'index efficace mais la seconde nécessiterait un scan de table complet).Si vos liens n'étaient pas bidirectionnels, il ne serait pas nécessaire de savoir qui sont les amis de A, mais vous en aurez probablement toujours besoin car vous aurez probablement besoin de savoir de qui B est un ami.

+1

Je me demande comment vous formulez une requête de jointure avec deux clés étrangères (userIDLink1 et userIDLink2) pointant sur la même clé primaire? – koceeng

-1

Créer une table unique pour tous les amis et donner à chaque ami un UserSid qui est égale à leurs utilisateurs respectifs clés

0

Créer une table qui contient tous les amis Chaque ligne de la table contient l'ID de l'utilisateur et l'identifiant de leur ami

+0

Donc pour chaque ami de chaque utilisateur, j'ajoute une ligne dans un tableau à 2 colonnes (Utilisateur, Ami). Par exemple, si j'ai 200 utilisateurs avec 10 amis chacun, la table "Amis" devrait avoir 2000 lignes (10 par utilisateur). Est-ce que je comprends bien? – asmo

+1

@asmo c'est correct, mais avec une table hautement indexée comme vous pouvez avoir dans ce cas vous ne devriez pas avoir peur des tables avec plus d'un million de lignes - ce ne sera pas un problème. – Cruachan

7

en supposant que votre table USER a une clé primaire appelée id ou quelque chose de similaire, utilisez le tableau suivant:

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; 

Cette Setu p soutient que Pierre est un ami de Marie, mais Marie ne pense pas à Peter comme ça. Mais les données existent pour déduire que Peter est une connaissance pour Mary ...

La clé primaire étant les deux colonnes arrête également les doublons.

+0

Ai-je manqué l'assignation de 'FK_FRIENDS_1' là? – jcolebrand

+0

Plus propre avec user_id et friend_id – rigobcastro

1

Vous recherchez une table de jointure M-to-N ou many-to-many.

Tableau utilisateurs:

USER_ID integer primary key, 
NAME  varchar 

Tableau Friendships

USER_ID integer not null, 
FRIEND_ID integer not null, 

Les deux USER_ID et FRIEND_ID sont les clés étrangères qui font référence à la table des utilisateurs (utilisateurs.id_utilisateur).

Si l'utilisateur 123 est ami de l'utilisateur 921. Ajoutez la ligne (123, 921) à la table des amitiés.

+0

Vous montrez uniquement 2 tables? N'est-ce pas un un-à-plusieurs pour cela? – Notflip

Questions connexes