2009-07-11 9 views
1

Je cherche de l'aide avec le système de base de données, pas le "nuage" lui-même.PHP Tag Cloud

Dans un site où les utilisateurs soumettent des images et peuvent étiqueter des images, comment la base de données doit-elle être configurée pour une performance optimale?

Je pensais

ID - int(11), unique, auto_incremenet 
tag - varchar(20) 
imageID - int(11) 

donc je suppose une image uploader, et taguez "Toronto, sushi, été".

requête serait:

INSERT INTO tags (tag, imageID) VALUES ('$tag[0]', $imageID); 
INSERT INTO tags (tag, imageID) VALUES ('$tag[1]', $imageID); 
INSERT INTO tags (tag, imageID) VALUES ('$tag[2]', $imageID); 

ensuite pour récupérer, je vais choisir * à partir des balises où ImageID = $ imagID.

Y a-t-il un défaut?

Répondre

3

Vous devez avoir une relation HABTM (a et appartient à plusieurs) entre deux tables une pour les images, une pour les balises et une troisième table avec des combinaisons d'identifiants d'image et d'identifiants de balises. De cette façon, vous ne limitez pas le nombre de tags qu'une image peut avoir ou le nombre d'images auxquelles une étiquette peut appartenir et vous n'avez pas de duplication.

+0

J'ai fini par faire cela. Principalement parce que je pense que c'est la façon dont SoF le fait aussi, ce qui pourrait me permettre d'ajouter des colonnes supplémentaires à cette table, comme par exemple quel utilisateur a créé cette balise en premier, etc. – sqram

3

Je ne vois pas de réels problèmes avec cette approche si ce n'est que les images qui partagent le même tag ont des entrées en double dans la base de données. Si vous essayez de normaliser, vous vous retrouvez avec une table contenant des références en double à une autre table contenant les tags eux-mêmes, ce qui dans ce cas semble être une perte de temps (codage, jointure et déplacement de tables pour MySQL).

Une petite optimisation que je considérerais bien est l'ordre de vos colonnes. Groupez les 'int' ensemble, car ils ont une largeur fixe pour MySQL, ce qui signifie qu'ils peuvent être recherchés légèrement plus rapidement dans cet ordre que dans int varchar int.

1

J'utiliser une table d'étiquette distincte: balises TABLE: tag_id- int (11), unique, étiquette auto_incremenet - varchar (20)

TABLE image tags: 
ID - int(11), unique, auto_incremenet 
tag - varchar(20) 
imageID - int(11) 

Alors je regarde si l'étiquette est déjà là et insérera seulement les ID

INSERT INTO balises (tag, imageID) VALEURS ('$ tag_id [0]', $ imageID); INSERT INTO balises (tag, imageID) VALEURS ('$ tag_id [1]', $ imageID); INSERT INTO balises (tag, imageID) VALEURS ('$ tag_id [2]', $ imageID);

De cette façon, les images avec les mêmes tags seront plus faciles à trouver car elles partagent le même tag_id et pas seulement le même contenu varchar. Bien sûr, vous devez convertir les étiquettes en minuscules et remplacer les caractères spéciaux, etc.

1

Assurez-vous qu'il existe un index sur le champ imageID.

2

La modification du champ d'étiquette en un caractère (20) augmenterait également les performances? L'ensemble de la table deviendrait à largeur fixe et les requêtes exécutées sur des tables à largeur fixe sont généralement plus rapides - je suis donc amené à croire en ma récente étude sur la conception de DB. Être fixé à 20 caractères entraînera un léger surcoût en termes d'espace occupé par la table, mais c'est une petite table de toute façon je ne peux pas voir une taille de fichier légèrement plus grande étant un énorme problème.Cela dit, pour le fait même est une table minuscule, j'imagine que vous auriez besoin de beaucoup de lignes de données avant de voir une différence entre varchar (20) et char (20).

Juste une idée. :)