Wie Tags (Themen) möglichst günstig in Datenbank speichern?

3 Antworten

Hallo.

Wenn ich davon ausgehe, du hast irgendeine Art von Forum, ähnlich wie hier. Und du hast bereits eine Tabelle in der Datenbank mit den Beiträgen, im Idealfall mindestens zwei Spalten, nämlich die ID (integer auto increment primary key) und eben den Beitrag selbst (Text).

Dann schlage ich dir vor, eine zweite Tabelle anzulegen für die Tags.

Spalte Id (primary key)

Spalte Beitrag ID (Fremdschlüssel auf die ID der Tabelle mit den Beiträgen)

Spalte für die Tags (Text)

So kannst du zu jedem Beitrag beliebig viele Tags speichern, jeder Tag aber ist genau einem Beitrag zugeordnet (1:n Beziehung).

Die ID Spalte für die Tags ist vielleicht nicht zwangsläufig notwendig, vielleicht aber nützlich, wenn du z.B. einmal nach Duplikaten suchen möchtest.

Viel Erfolg


Niklas 
Fragesteller
 15.04.2017, 21:11

Danke für deine Antwort!

So kannst du zu jedem Beitrag beliebig viele Tags speichern, jeder Tag aber ist genau einem Beitrag zugeordnet (1:n Beziehung).

Wäre das andersherum nicht sinnvoller, jedem Beitrag die entsprechenden Tags zuzuweisen? Wenn jedes Mal, wenn ein Tag gespeichert wird, ein neuer Eintrag in die Tabelle geschrieben wird... da entsteht ja ein extrem hohes Datenaufkommen.

0
Niklas 
Fragesteller
 15.04.2017, 21:14
@Niklas

Ich dachte mehr daran, die Tags in einer Spalte in der Beitrags-Tabelle zu speichern, etwa kommagetrennt. Würde jede Menge Platz sparen und wäre wesentlich übersichtlicher.

Allerdings wäre deine Methode vermutlich einfacher, was das Entfernen von Tags aus Beiträgen geht. Die Plattform soll ja auch moderiert werden können.

0
tilfuerst  15.04.2017, 21:42
@Niklas

Ja, die Gedanken sind nicht verkehrt. Ich möchte mal zu zwei weiteren Varianten Stellung beziehen:

1. Du kannst auch eine n:n Beziehung aufbauen:

1) Tabelle mit Beiträgen (id, Beitrag)

2) Tabelle mit Tags (tag_id, tag-text)

3) Zuordnungstabelle (beitrag-id, tag-id)

Vorteile: Wird ein Tag für mehrere Beiträge vergeben, wird er nur einmal in der Datenbank hinterlegt. Das ist sauberer, und auch weiter normalisiert. Tags zu ändern bedarf auch nur noch einer einelnen Update Operation. Dazu kommt, das das Suchen nach Beiträgen mit einem Bestimmten Tag performanter ist, als mit der Variante meiner ursprünglichen Antwort.

Nachteil: Der höhere Programmieraufwand. Du musst zum Einen einen Join über drei Tabellen schreiben, was jetzt vielleicht nicht so das Problem ist. Beim anlegen von Tags musst du zuerst suchen, ob dieser schon existiert, wenn ja, diesen zuordnen, wenn nein dann neu anlegen und den neuen zuordnen --> (upsert Verfahren). 

2. Dein Vorschlag zum kommagetrennten Speichern.

Der Vorteil liegt in weniger langen Tabellen. Allerding musst die Datenbank bei der Suche nach Beiträgen zu einem bestimmten Tag in allen Werten zunächst Zeichenketten-Operationen (string.split(",")) durchführen. Die Performance würde wohl erheblich darunter leiden.

Solltest du die Idee trotzdem umsetzen wollen, schau dir mal PostgreSQL an, genauer den Datentyp JSONB. (gibt es bei mysql bzw. Maria meines Wissens so nicht). JSONB in Postgres indiziert dir deine JSON Dokumente was den von mir genannten Performance Nachteil komplett wieder ausbügelt.

https://blog.codeship.com/unleash-the-power-of-storing-json-in-postgres/

Viel Erfolg.

0

Es wäre gut zu wissen wie deine momentane Datenbank aufgebaut ist, in der die Themen gespeichert werden.
Aber gehen wir mal davon aus, dass du eine Tabelle für die Beiträge und eine weitere für die Themen hast.
Jeder Beitrag sollte dann eine Unikat-ID haben. Die Spalte ID sollte sein: INT, unsigned, index primary, auto increment.
Und die Tabelle für die Themen sollte eine Spalte "beitrag_id" enthalten. INT 50 sollte reichen :D
So kannst du den Themen die ID des Beitrags zuweisen.
Lg


Niklas 
Fragesteller
 15.04.2017, 21:12

Danke für deine Antwort.

Aber wie trenne ich denn dann mehrere Themen, die in einer Spalte stehen?

Derzeit habe ich 4 Themen-Spalten, pro Spalte wird ein Thema (Tag) gespeichert.

0
mrGalileo  15.04.2017, 22:26
@Niklas

Achso. Ich glaube ich habe mich verlesen.
Wenn du einem Beitrag tags zuweisen willst, brauchst du nur eine Spalte wo du die Tags drin speicherst. Einfach per Kommata trennen und bei der auslese diese dann mit explode trennen.

1

Was sind das für Tags, wie schauen diese aus und wofür benötigst Du diese? Willst Du die Tags nur zum Anschauen speichern und von Hand suchen, weil sie durch Komma getrennt wesentlich übersichtlicher sein sollen? Wie soll PHP die kommagetrennten Tags trennen, wenn es gar keine Tags hat? Die Tags sind doch in der Datenbank. Wie soll PHP an die Tags kommen?

Was verstehst Du unter extrem hohem Datenaufkommen durch das Speichern? Da musst Du was falsch verstanden haben.

Maßgebend für die Gestaltung einer Datenverwaltung ist, besonders wenn sie wie hier besonders günstig sein soll, der spätere Verwendungszweck. Davon ist hier aber keine Rede. Man kann zwar vermuten, was Du da vorhast, aber das reicht nicht aus, um vernünftige Vorschläge zu machen. Normalerweise ist zur Lösung einer Aufgabe eine genaue Kenntnis des Vorhabens und des Umfeldes erforderlich.

Die Datenbank ist ein Werkzeug zum Speichern und Wiederfinden von strukturierten Daten. Dazu bietet sie eine Menge Speicher- und Suchtechniken in Form von Anweisungen an, mit deren Hilfe man die Daten nach den Erfordernissen einer bestimmten Aufgabe verwalten kann. Zur Verarbeitung der Daten, soweit dies über die Datenverwaltung hinausgeht, sind gemäß der anstehenden Aufgabe geeignete Programmiersysteme (u.a. PHP) nötig, die ihrerseits mit der Datenbank in direkter Verbindung stehen.

Die Datenbank macht nichts von alleine. Jedes kleinste Detail muss minuziös durchdacht und formuliert werden. Am besten ist es, man stellt sich vor, man wäre selbst die Datenbank und müsste alles selber machen. Dann weiß man auch, wie man das der Datenbank mitteilen muss. Das ist wie im richtigen Leben: Ein Vorgesetzter kann auch keine Tätigkeit deligieren, wenn er selber nicht weiß, wie sie geht.