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?

Logan Serman
quelle
2
Zuvor gefragt: stackoverflow.com/questions/20856/…
DrBloodmoney
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.

Simon Scarfe
quelle
Siehe auch
Cherian
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.

Rob Kennedy
quelle
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.

Neil Barnwell
quelle
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.

Dmitry Shvedov
quelle
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.

Valentin Vasilyev
quelle
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.

Rockcoder
quelle
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.

Adam Pope
quelle
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.

Timothy Khouri
quelle