Vous devez garder une trace de la fréquence à laquelle une variable est liée à une autre. Comme, disons "php" et "mysql" partagent 50 articles (ou quel que soit le contenu principal marqué), alors que "php" et "sql-server" peuvent en avoir 3, et "php" et "apache" en ont 25. étant donné "php", vous devriez retourner "mysql" et "apache" dans cet ordre (en laissant éventuellement "sql-server" tomber à l'eau).
Absolument pas idéal, juste à y penser à haute voix (et le type d'expansion sur la réponse de stephenc, maintenant que je vois):
CREATE TABLE tag_relations (
tag_id int unsigned not null,
related_tag_id int unsigned not null,
relation_count smallint unsigned not null,
PRIMARY KEY (tag_id, related_tag_id),
KEY relation_count (relation_count)
);
Ensuite, pour chaque balise liée à un article, une boucle à travers tous les d'autres tags et INSERT/UPDATE, incrémentant le relation_count de 1. Cela signifie ("php", "mysql") et ("mysql", "php") sont deux relations complètement différentes à maintenir, mais sans creuser à travers les concepts de recherche I J'ai probablement oublié, ça fonctionnera toujours. Si quelque chose a 10+ tags, les mises à jour seront très lentes (peut-être passer à cron comme stephenc suggéré), mais il sera plus facile de chercher de cette façon. Nice et simple comme ceci:
SELECT related_tag_id, COUNT(relation_count) AS total_relations
FROM tag_relations
WHERE tag_id IN ([list,of,tag,IDs,to,compare])
// AND tag_id NOT IN ([list,of,tag,IDs,to,compare]) -- probably
GROUP BY related_tag_id
ORDER BY total_relations DESC
plus facile que d'avoir à vérifier à la fois contre tag_id
& related_tag_id
et les résumer par un gâchis de sous-requêtes, au moins. REJOIGNEZ-NOUS sur votre table de tags pour obtenir les tagnames & vous êtes prêt. Donc, si vous cherchez "php" et "mysql", et "apache" se rapporte souvent aux deux, ce sera près du sommet car il compte & en pondérant chaque relation commune. Il ne sera pas strictement limiter aux liens communs, alors ajoutez HAVING total_relations >= x
(x étant une coupure arbitraire) et/ou juste un LIMIT x
régulier pour garder les choses pertinentes.
(note: la recherche diable de cette avant de penser à ce qui est encore un peu utile - je suis sûr qu'il ya un algorithme connu là-bas qui est 100x plus intelligent et je ne suis pas en souvenir.)
PHPro. org a un good writeup aussi, en utilisant une idée similaire.
Voulez-vous le stocker aux deux endroits, et utilisez-vous simplement la chaîne pour les recherches d'entrées connexes? En ce moment mon plan d'avoir les étiquettes pas dans la table d'entrées est pour des recherches rapides et faciles par l'étiquette et pour l'utilisation de complétion automatique dans la zone d'entrée de balises avec d'autres utilisations potentielles. – gokujou
Je parle d'utiliser la chaîne SEULEMENT pour récupérer des entités, pour rendre la requête de sélection beaucoup plus simple (et rapide). La recherche sera plus efficace avec join-table. – zerkms