Was ist der effizienteste Weg, um Tags in einer Datenbank zu speichern?


138

Ich implementiere auf meiner Website ein Tagging-System, das einem Stackoverflow ähnelt. Meine Frage lautet: Wie können Tags am effektivsten gespeichert werden, damit sie durchsucht und gefiltert werden können?

Meine Idee ist folgende:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Ist das zu langsam? Gibt es einen besseren Weg?



1
Verwenden Sie ab 2016 Solr oder Elasticsearch
Charles L.

Antworten:


189

Ein Artikel wird viele Tags haben. Und ein Tag gehört zu vielen Gegenständen. Dies bedeutet für mich, dass Sie möglicherweise einen Zwischentisch benötigen, um das Viele-zu-Viele-Hindernis zu überwinden.

Etwas wie:

Tabelle:
Elemente Spalten: Element_ID, Element_Titel, Inhalt

Tabelle: Tags
Spalten: Tag_ID, Tag_Title

Tabelle: Items_Tags
Spalten: Item_ID, Tag_ID

Es kann sein, dass Ihre Web-App wahnsinnig beliebt ist und später denormalisiert werden muss, aber es ist sinnlos, das Wasser zu früh zu trüben.



Wenn es etwas wie tagGroup gibt, wie man damit umgeht, z. B. werden die Tags in Kategorien gruppiert, z. B.: Programmiersprachen: c #, vb, pearl. Betriebssystem: Windows 7, Dos, Linux usw.
Thunder

4
@Thunder: Unter der Annahme, dass ein Tag nur zu einer Kategorie gehört, würde ich eine TagCategory-Tabelle erstellen, die aus category_id und category_name besteht. Von dort würde ich ein Feld category_id an die Tags-Tabelle anhängen und einen Join dazu durchführen.
Simon Scarfe

113

Sie sollten die Blog-Beiträge von Philipp Keller über das Markieren von Datenbankschemata lesen. Er probiert einige aus und berichtet über seine Ergebnisse, sowohl hinsichtlich der einfachen Erstellung allgemeiner Abfragen als auch hinsichtlich der Leistung . Die Anzahl der Tags, die Anzahl der markierten Elemente und die Anzahl der Tags pro Element waren alles Faktoren. Die Beiträge stammen aus dem Jahr 2005; Seitdem sind mir keine Updates bekannt.


19
Ich denke, das ist die beste Antwort. Es basiert eher auf tatsächlichen Tests und Untersuchungen als auf Vermutungen wie die meisten anderen Antworten.
Cristian Vrabie

4
Die Links in der Antwort scheinen nicht zu funktionieren. Gefunden eine Kopie bei vtidter.blogspot.be/2014/02/database-schema-for-tags.html
Christophe Herreman

8

Eigentlich glaube ich, dass eine De-Normalisierung der Tags-Tabelle je nach Skalierung ein besserer Weg sein könnte.

Auf diese Weise hat die Tags-Tabelle einfach Tagid, Itemid, Tagname.

Sie erhalten doppelte Tagnamen, aber das Hinzufügen / Entfernen / Bearbeiten von Tags für bestimmte Elemente wird dadurch VIEL einfacher. Sie müssen kein neues Tag erstellen, die Zuordnung des alten entfernen und ein neues neu zuweisen. Sie bearbeiten lediglich den Tag-Namen.

Zum Anzeigen einer Liste von Tags verwenden Sie einfach DISTINCT oder GROUP BY, und natürlich können Sie auch zählen, wie oft ein Tag problemlos verwendet wird.


4

Wenn es Ihnen nichts ausmacht, ein bisschen nicht standardmäßiges Material zu verwenden, bietet Postgres ab Version 9.4 die Option, einen Datensatz vom Typ JSON-Textarray zu speichern.

Ihr Schema wäre:

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

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

Weitere Informationen finden Sie in diesem ausgezeichneten Beitrag von Josh Berkus: http://www.databasesoup.com/2015/01/tag-all-things.html

Es gibt mehr verschiedene Optionen, die hinsichtlich der Leistung gründlich verglichen werden, und die oben vorgeschlagene ist insgesamt die beste.


2

Ich würde vorschlagen, eine zwischengeschaltete dritte Tabelle zum Speichern von <=> Elementzuordnungen für Tags zu verwenden, da wir viele-zu-viele-Beziehungen zwischen Tags und Elementen haben, dh ein Element kann mehreren Tags zugeordnet werden, und ein Tag kann mehreren Elementen zugeordnet werden. HTH, Ventil.


1

Sie können nicht wirklich über Langsamkeit sprechen, basierend auf den Daten, die Sie in einer Frage angegeben haben. Und ich denke nicht, dass Sie sich in dieser Entwicklungsphase zu viele Sorgen um die Leistung machen sollten. Es heißt vorzeitige Optimierung .

Ich würde jedoch vorschlagen, dass Sie die Spalte Tag_ID in die Tags-Tabelle aufnehmen. Es ist normalerweise eine gute Praxis, dass jede Tabelle eine ID-Spalte hat.


1

Wenn Speicherplatz ein Problem sein soll, haben Sie eine dritte Tabelle Tags (Tag_Id, Titel), um den Text für das Tag zu speichern, und ändern Sie dann Ihre Tags-Tabelle in (Tag_Id, Item_Id). Diese beiden Werte sollten auch einen eindeutigen zusammengesetzten Primärschlüssel liefern.


0

Elemente sollten ein "ID" -Feld und Tags ein "ID" -Feld (Primärschlüssel, Clustered) haben.

Erstellen Sie dann eine Zwischentabelle mit ItemID / TagID und setzen Sie dort den " Perfect Index " ein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.