2009-01-23 7 views
2

Quelle serait la meilleure façon de structurer une "fonction" d'ami.
C'est ce que je pense: Disons que j'ai un usertable avec les colonnes suivantes: user_id, nom d'utilisateur, mot de passe ... et une table par le nom des amis avec des colonnes: friend1, friend2, accepted.Fonction d'ami SQL

Si utilisateur2 ajoute user1 Je veux utilisateur2 à afficher sur le profil de l'utilisateur 1 et USER1 USER2 années ...: O

cela semble un peu désordonné ... est-il un moyen plus intelligent?

Répondre

4
CREATE TABLE (friend_id_a, friend_id_b, accepted) 

Définir une contrainte: friend_id_a < friend_id_b.

Remplissez la table avec vos entités comme suit:

INSERT 
INTO friend_friend(friend_id_a, friend_id_b) 
VALUES (LEAST(@id1, @id2), GREATEST(@id1, @id2)) 

Pour sélectionner tous les amis d'une personne:

SELECT friend_id_b 
FROM friend_friend 
WHERE friend_id_a = @id 
AND accepted 
UNION ALL 
SELECT friend_id_a 
FROM friend_friend 
WHERE friend_id_b = @id 
AND accepted 

UNION ALL ici vous permet d'utiliser les index et éviter le tri supplémentaire pour l'unicité.

Tout ce qui précède est valable pour "l'amitié" en tant que relation symétrique et anti-réflexive. Cela signifie que:

  • Si un est ami à b, puis b est ami à un

  • un est jamais un ami à un

1

Je pense que votre design est bon. La deuxième table friends (friend1 clé primaire, friend2), où une rangée f1, f2 est présent si « l'amitié entre f1 et f2 est sur le point d'être mis en place », et accepted est vrai si elle a été effectivement mis en place, est la bonne façon de représentent une relation plusieurs-à-plusieurs.

(Le seul problème avec l'approche naïve est quand vous devez vérifier que f1 est un ami de f2 « s: Cela peut vouloir dire que la ligne f1, f2 est présent, ou que la ligne f2, f1 +1 à Quassnoi pour avoir surmonté cette difficulté.)

1

Je ne peux pas dire si vous voulez dire une table massive avec une colonne pour chaque ami, ou deux tables comme ci-dessous, mais cette dernière est la meilleure.

[dbo].[Users]{ 
    User_ID int, 
    UserName VarChar, 
    Password ... 
} 

[dbo].[Friends]{ 
    User1_ID int, 
    User2_ID int, 
    Accepted bit 
}