2009-05-22 7 views
3

J'ai créé un site d'actualités: - Les articles sont affichés sur la première page, classés par date. Le plus récent en premier. - Les nouvelles sont dans le tableau "news" avec les champs "id", "title", "text" et quelques autres. - Tous les articles sont étiquetés avec 1-5 tags appropriés. - Les tags sont dans la table "tags" avec les champs "id", "tag", "article" et quelques autres. - Le champ "article" de "tags" correspond au champ "id" de "news".Meilleure structure DB (MySQL): articles qui contiennent des tags favoris

Maintenant, je veux donner à l'utilisateur la possibilité d'ajouter des balises à sa "liste de balises préférées". Ensuite, l'utilisateur ne doit voir que les articles de presse contenant l'un des tags favoris.

En supposant que l'utilisateur Bob a favorisé les étiquettes "barack obama", "nba", "new jersey" et "chiens". Il devrait seulement voir les articles contenant au moins un de ces quatre étiquettes.

Comment puis-je coder un script PHP/MySQL qui réalise cela? Je pense que ma structure de base de données n'est pas adéquate à cet effet, n'est-ce pas? Je devrais faire des requêtes DB comme ceci:

"SELECT * FROM nouvelles OERE IN ID (SELECT article de balises WHERE tag IN ('barack obama', 'nba', 'new jersey', 'chiens')) "

Cette requête devrait durer longtemps, n'est-ce pas? Il doit y avoir une structure de base de données plus appropriée que la mienne. Avez-vous une idée de ce problème? De quelle structure DB ai-je besoin et quelles requêtes dois-je utiliser?

J'espère que vous pouvez m'aider. Merci d'avance!

Répondre

8

Ce qui suit n'est en aucun cas exhaustif/définitif, mais il devrait vous aider à aller dans la bonne direction.

Tables:

news 
===== 
id 
title 
text 

tag 
=== 
id 
tag 

tag_map 
======= 
tag_id 
news_id 

favorite_tags 
============= 
user_id 
tag_id 

Query

SELECT * 
FROM favorite_tags 
JOIN tag_map ON favorite_tags.tag_id = tag_map.tag_id 
JOIN news ON tag_map.news_id = news.id 
WHERE favorite_tags.user_id = $userid 
+0

Merci beaucoup pour cette réponse rapide et bonne. J'ai une dernière question: Sur quels champs dois-je définir un index? J'ai choisi "id" comme primaire dans "news", "id" comme un primaire et "tag" comme un unique dans "tag", "tag_id, news_id" en tant que primaire et "news_id" dans "tag_map" et , enfin, "user_id, tag_id" en tant que primaire et "tag_id" dans "favorite_tags". Est-ce correct? – caw

+0

D'un coup d'oeil rapide, il semble à peu près correct, mais, vérifiez en remplissant les tables et en faisant 'EXPLAIN SELECT' etc. –

+0

Je pense que vous voulez des index sur tag_map.tag_id, news.id, et favorite_tags.user_id, pour cela question. –

1

performance de la requête (que ce soit dans votre sous-select approche, ou Frank Farmer plus élégante rejoindre basée sur un) dépendra essentiellement des indices. Rappelez-vous simplement que MySQL utilise un seul index par table, et le bon ensemble d'indices (en fonction de la requête que vous voulez optimiser) devient invariablement assez évident ...

+0

Merci, j'ai ajouté une question concernant les indices à la réponse de Frank Farmer. – caw

Questions connexes