Meilleure méthode pour stocker une liste d'ID d'utilisateur

je travaille sur un système de notation PHP/MySQL en ce moment. Pour l'utilisateur d'être en mesure d'évaluer l'utilisateur doit ouvrir une session. Chaque utilisateur a un "UID"unique. Il y aura plusieurs instances de notation sur le site Web (une pour chaque jeu, dans mon cas) et j'ai besoin d'un moyen efficace de stocker une liste D'UIDs dans une ligne MySQL (une ligne MySQL dans la table de notation pour chaque instance du système de notation) pour garder un décompte de qui a voté.

j'ai vu dans d'autres systèmes que la liste est stockée dans un tableau PHP sérialisé. Chaque fois qu'un utilisateur vote, alors le tableau sérialisé doit être extrait, non sérialisé, le nouvel UID est inséré, le tableau est re-sérialisé, et la ligne MySQL est mise à jour. Chaque fois que la page est chargée, cette liste doit de nouveau être non numérisée et vérifiée pour voir si l'utilisateur qui regarde la page a encore voté pour s'assurer que l'utilisateur ne vote pas deux fois.

cela semble un peu inefficace et encombrant. Est-ce que MySQL a une fonction de liste intégrée pour aider ceci processus d'être plus efficace? Y a-t-il d'autres moyens intelligents de résoudre ce problème?

j'ai considéré une alternative possible qui est d'oublier la sérialisation et de stocker les UIDs dans un champ de type de texte dans la base de données MySQL. Je voudrais juste ajouter un caractère non-numérique après chaque UID (disons une période [.]). Pour ajouter une entrée utilisateur, je concaténerai l'UID à la fin du champ de texte, puis une période. En vérifiant si l'Utilisateur a déjà voté je pourrais juste "SELECT * FROM table WHERE votes =' %$UID.%";". Cela fonctionnerait-il plus efficacement ou y a-t-il une façon plus élégante de faire le travail?

Post de suivi sur la structure de la table... structure de table MySQL efficace pour le système de notation

4
demandé sur Joel Verhagen 2009-03-07 01:15:20

2 réponses

c'est inefficace. Ce que vous avez ici en termes relationnels est une relation de plusieurs à plusieurs entre les utilisateurs et les jeux. Un utilisateur peut voter sur de nombreux jeux. Un jeu peut être voté par de nombreux utilisateurs. La solution pour cela est d'avoir une table de jointure:

USERS (uid, name, ...)
GAMES (gid, name, ...)
VOTES (id, uid, gid, ...)

où uid et gid sont des clés étrangères de retour à leurs tables respectives.

si quelqu'un vote, inscrire une mention dans VOTES.

Pour obtenir une liste de voix pour un jeu:

$get = mysql_query("SELECT * FROM votes WHERE gid = $game_id");
...

pour obtenir une liste des votes de l'utilisateur:

$get = mysql_query("SELECT * FROM votes WHERE uid = $user_id");
...

et ainsi de suite.

ne pas joindre un tableau et le stocker dans une seule colonne. Vous avez raison pour l'éviter.

17
répondu cletus 2009-03-06 22:18:58

dans une base de données normalisée, vous devez la stocker dans une table de jonction:

UserRatings
-------------
RatingID int
UserID int
UserVote int

je ne sais pas quelles sont vos requêtes. Selon l'application, cela pourrait ne pas avoir la performance acceptable. Cependant, dans un cas comme dans l'autre, je vous suggère d'adopter l'approche normalisée, le point de référence et la dénormalisation seulement s'il y a lieu.

4
répondu Mehrdad Afshari 2009-03-06 22:18:48