Normalerweise würde ich Yaakov Ellis zustimmen, aber in diesem speziellen Fall gibt es eine andere praktikable Lösung:
Verwenden Sie zwei Tabellen:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
Dies hat einige wesentliche Vorteile:
Erstens macht es die Entwicklung viel einfacher: In der Drei-Tabellen-Lösung zum Einfügen und Aktualisieren müssen item
Sie die Tag
Tabelle nachschlagen, um festzustellen , ob bereits Einträge vorhanden sind. Dann musst du sie mit neuen verbinden. Dies ist keine triviale Aufgabe.
Dann werden Abfragen einfacher (und möglicherweise schneller). Es gibt drei wichtige Datenbankabfragen, die Sie ausführen werden: Alle Tags
für einen Item
ausgeben, eine Tag-Cloud zeichnen und alle Elemente für einen Tag-Titel auswählen.
Alle Tags für einen Artikel:
3-Tabelle:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2-Tabelle:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
Tag-Cloud:
3-Tabelle:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2-Tabelle:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
Artikel für einen Tag:
3-Tabelle:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2-Tabelle:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
Es gibt jedoch auch einige Nachteile: Es kann mehr Speicherplatz in der Datenbank beanspruchen (was zu mehr langsameren Festplattenoperationen führen kann) und es wird nicht normalisiert, was zu Inkonsistenzen führen kann.
Das Größenargument ist nicht so stark, da Tags naturgemäß ziemlich klein sind, sodass die Größenerhöhung nicht groß ist. Man könnte argumentieren, dass die Abfrage nach dem Tag-Titel in einer kleinen Tabelle, die jedes Tag nur einmal enthält, viel schneller ist, und dies ist sicherlich wahr. Wenn man jedoch die Einsparungen berücksichtigt, die entstehen, wenn man nicht beitreten muss, und die Tatsache, dass man einen guten Index darauf aufbauen kann, könnte dies leicht kompensiert werden. Dies hängt natürlich stark von der Größe der von Ihnen verwendeten Datenbank ab.
Das Inkonsistenzargument ist ebenfalls ein wenig umstritten. Tags sind Freitextfelder und es wird keine Operation wie "Alle Tags" foo "in" bar "umbenennen" erwartet.
Also tldr: Ich würde mich für die Zwei-Tabellen-Lösung entscheiden. (In der Tat werde ich. Ich habe diesen Artikel gefunden, um zu sehen, ob es gültige Argumente dagegen gibt.)