281 votes

Comment me conseillez-vous d’application d’étiquettes ou de marquage

J’ai entendu parler de plusieurs façons de mettre en place le marquage ; à l’aide d’une table de mappage entre TagID et ItemID (logique pour moi, mais il n’évolue pas ?), ajout d’un nombre fixe de colonnes de TagID possibles à ItemID (semble être une mauvaise idée), gardant les tags dans une colonne de texte qui est virgule séparées (sons fou mais pourrait fonctionner). J’ai même entendu quelqu'un recommande une matrice clairsemée, mais alors comment les noms de balise grandissent-ils gracieusement ?

Est-ce que je suis absent une pratique exemplaire pour les balises ?

395voto

Yaakov Ellis Points 15470

Trois tableaux (un pour le stockage de tous les éléments, un pour toutes les balises et un pour la relation entre les deux), correctement indexées, avec des clés étrangères en cours d’exécution sur une base de données approprié, la valeur devrait fonctionnent bien et correctement à l’échelle.

81voto

Scheintod Points 1024

Normalement je suis d'accord avec Yaakov Ellis, mais dans ce cas spécial, il y a une autre solution viable:

L'utilisation de deux tables:

Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID

Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title

Cela a quelques avantages majeurs:

D'abord, il rend le développement plus simple: dans les trois tables solution pour l'insertion et la mise à jour de item que vous avez à la recherche de l' Tag tableau pour voir si il y a déjà entrées. Ensuite, vous avez à se joindre à eux avec de nouveaux. Ce n'est pas une tâche triviale.

Alors il fait des requêtes plus simple (et peut-être plus rapide). Il existe trois principales requêtes de base de données qui vous permettra de faire: Sortie tous Tags pour un Item, dessiner un Tag-Cloud et de sélectionner tous les éléments pour une Balise de Titre.

Toutes les Balises d'un Article:

3-Tableau:

SELECT Tag.Title 
  FROM Tag 
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 WHERE ItemTag.ItemID = :id

2-Tableau:

SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id

Tag-Cloud:

3-Tableau:

SELECT Tag.Title, count(*)
  FROM Tag
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 GROUP BY Tag.Title

2-Tableau:

SELECT Tag.Title, count(*)
  FROM Tag
 GROUP BY Tag.Title

Éléments pour une Balise:

3-Tableau:

SELECT Item.*
  FROM Item
  JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
  JOIN Tag ON ItemTag.TagID = Tag.TagID
 WHERE Tag.Title = :title

2-Tableau:

SELECT Item.*
  FROM Item
  JOIN Tag ON Item.ItemID = Tag.ItemID
 WHERE Tag.Title = :title

Mais il y a quelques inconvénients: Il pourrait prendre plus d'espace dans la base de données (ce qui pourrait conduire à plus d'opérations sur le disque dur qui est plus lent) et il n'est pas normalisée qui pourrait conduire à des incohérences.

La taille de l'argument n'est pas forte parce que la nature de balises, c'est qu'ils sont normalement assez petit, de sorte que l'augmentation de la taille n'est pas un grand. On pourrait faire valoir que la requête pour la balise de titre est beaucoup plus rapide dans un petit tableau qui contient chaque balise qu'une seule fois et ce n'est certainement vrai. Mais à prendre en ce qui concerne les économies pour ne pas avoir à se joindre et le fait que vous pouvez construire un indice sur eux pourrait facilement compenser pour cela. Bien sûr, cela dépend fortement de la taille de la base de données que vous utilisez.

L'incohérence de l'argument est un peu discutable. Les balises sont des champs de texte libre et il n'est pas prévu de l'opération comme " renommer toutes les balises "foo", "bar"'.

Donc tldr: je pencherais pour les deux tables de la solution. (En fait, je vais le faire. J'ai trouvé cet article pour voir si il y a des arguments valables contre elle.)

37voto

Nick Retallack Points 5994

Réduction de mappage si vous utilisez une base de données qui prend en charge, comme couchdb, stocker des balises dans un champ de texte brut ou liste est en effet le meilleur moyen. Exemple :

Cela exécute avec groupe = true vont regrouper les résultats par nom de balise, et même de retour le nombre de fois où le balise a été rencontré. Il est très similaire à compter les occurrences d’un mot dans le texte.

12voto

David Schmitt Points 29384

Utiliser un seul texte mis en forme de colonne[1] pour stocker les balises et l'utilisation d'un moteur de recherche plein texte à l'index. Sinon vous serez confronté à des problèmes d'évolutivité lors de la tentative de mettre en œuvre des requêtes booléennes.

Si vous avez besoin de détails sur les étiquettes que vous avez, vous pouvez garder une trace de cela dans une manière incrémentielle maintenu table ou d'exécuter un travail par lots pour extraire l'information.

[1] Certains SGBDR même un natif de type tableau qui pourrait être encore mieux adapté pour le stockage en n'ayant pas besoin d'une analyse de l'étape, mais peut causer des problèmes avec la recherche plein texte.

9voto

Mark Biek Points 41769

J’ai toujours gardé les balises dans une table séparée et avait ensuite une table de mappage. Bien sûr je n’ai jamais fait quoi que ce soit à très grande échelle non plus.

Avoir une table « tags » et une table à carte, il est assez trivial pour générer des nuages de tag & tel puisque vous pouvez facilement remonter SQL pour obtenir une liste des balises avec les comtes de combien de fois chaque balise est utilisée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X