web-dev-qa-db-fra.com

Quel est le moyen le plus efficace de stocker des étiquettes dans une base de données?

J'implémente un système de marquage sur mon site Web similaire à celui utilisé par un stackoverflow. Ma question est la suivante: quel est le moyen le plus efficace de stocker les balises afin de pouvoir les rechercher et les filtrer?

Mon idée est la suivante:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Est-ce trop lent? Y a-t-il un meilleur moyen?

131
Logan Serman

Un article va avoir beaucoup de tags. Et une étiquette appartiendra à de nombreux articles. Cela signifie pour moi que vous aurez peut-être besoin d'une table intermédiaire pour surmonter l'obstacle de la multiplicité à la multiplicité.

Quelque chose comme:

Tableau: Articles
Colonnes: Item_ID, Item_Title, Content

Tableau: Tags
Colonnes: Tag_ID, Tag_Title

Table: Items_Tags
Colonnes: Item_ID, Tag_ID

Votre application Web est peut-être incroyablement populaire et nécessite une dénormalisation sur la route, mais il est inutile de brouiller les cartes trop tôt.

181
Simon Scarfe

Vous devriez lire les billets du blog de Philipp Keller sur le balisage des schémas de base de données. Il en essaye quelques-uns et rapporte ses résultats, à la fois en en termes de facilité de construction de requêtes courantes , et en en termes de performances . Le nombre d'étiquettes, le nombre d'éléments étiquetés et le nombre d'étiquettes par élément étaient tous des facteurs. Les postes sont de 2005; Je ne suis au courant d'aucune mise à jour depuis.

106
Rob Kennedy

En fait, j’estime qu’une dénormalisation du tableau des balises pourrait constituer une meilleure solution, en fonction de l’échelle.

De cette façon, la table des tags a simplement tagid, itemid, tagname.

Vous obtiendrez des noms de variables en double, mais cela simplifiera beaucoup l'ajout/la suppression/la modification de balises pour des éléments spécifiques. Vous n'avez pas besoin de créer une nouvelle balise, de supprimer l'allocation de l'ancienne et de réaffecter une nouvelle, il vous suffit d'éditer la variable.

Pour afficher une liste de balises, utilisez simplement DISTINCT ou GROUP BY, et vous pouvez bien sûr compter le nombre de fois où une balise est facilement utilisée.

7
Neil Barnwell

Si cela ne vous dérange pas d'utiliser des éléments non standard, Postgres version 9.4 et ultérieure dispose d'une option permettant de stocker un enregistrement de type tableau de texte JSON.

Votre schéma serait:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Pour plus d'informations, consultez cet excellent article de Josh Berkus: http://www.databasesoup.com/2015/01/tag-all-things.html

Il existe plus d'options différentes comparées à fond pour la performance et celle suggérée ci-dessus est la meilleure dans l'ensemble.

3
Dmitry Shvedov

Nous suggérons d’utiliser une troisième table intermédiaire pour stocker les associations de balises <=>, car nous avons des relations multiples entre balises et éléments, c’est-à-dire qu’un élément peut être associé à plusieurs balises et qu’une balise peut être associée à plusieurs éléments. HTH, Valve.

2
Valentin

Vous ne pouvez pas vraiment parler de lenteur à partir des données que vous avez fournies dans une question. Et je ne pense pas que vous devriez même vous soucier de la performance à ce stade de développement. Cela s'appelle optimisation prématurée .

Cependant, je suggérerais d'inclure la colonne Tag_ID dans la table des balises. C'est généralement une bonne pratique que chaque table ait une colonne ID.

1
Rockcoder

Si l'espace risque de poser problème, installez une 3ème table Balises (Tag_Id, Title) pour stocker le texte de la balise, puis modifiez la table Balises en (Tag_Id, Item_Id). Ces deux valeurs doivent également fournir une clé primaire composite unique.

1
Adam Pope

Les éléments doivent avoir un champ "ID" et les balises doivent avoir un champ "ID" (clé primaire, en cluster).

Créez ensuite une table intermédiaire ItemID/TagID et placez-y le " Perfect Index ".

0
Timothy Khouri