Zwykle zgodziłbym się z Yaakovem Ellisem, ale w tym szczególnym przypadku istnieje inne realne rozwiązanie:
Użyj dwóch tabel:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
Ma to kilka głównych zalet:
Po pierwsze, programowanie jest znacznie prostsze: w rozwiązaniu z trzema tabelami do wstawiania i aktualizacji item
musisz sprawdzić Tag
tabelę, aby sprawdzić, czy są już wpisy. Następnie musisz dołączyć do nich z nowymi. To nie jest trywialne zadanie.
Dzięki temu zapytania stają się prostsze (a być może szybsze). Istnieją trzy główne zapytania do bazy danych, które należy wykonać: Wyprowadź wszystko Tags
dla jednego Item
, narysuj chmurkę tagów i wybierz wszystkie elementy dla jednego tytułu tagu.
Wszystkie tagi dla jednej pozycji:
3-stół:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2-stół:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
Tag-Cloud:
3-stół:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2-stół:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
Produkty dla jednego tagu:
3-stół:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2-stół:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
Ale są też pewne wady: może zająć więcej miejsca w bazie danych (co może prowadzić do większej liczby operacji na dysku, co jest wolniejsze) i nie jest znormalizowany, co może prowadzić do niespójności.
Argument wielkości nie jest tak silny, ponieważ sama natura tagów polega na tym, że zwykle są one dość małe, więc wzrost rozmiaru nie jest duży. Można argumentować, że zapytanie o tytuł znacznika jest znacznie szybsze w małej tabeli, która zawiera każdy znacznik tylko raz, a to z pewnością jest prawdą. Ale biorąc pod uwagę oszczędności wynikające z rezygnacji z przyłączenia się oraz fakt, że można na nich zbudować dobry indeks, można to łatwo zrekompensować. Zależy to oczywiście w dużej mierze od wielkości używanej bazy danych.
Argument o niekonsekwencji jest również trochę dyskusyjny. Tagi są polami tekstowymi i nie ma oczekiwanej operacji, takiej jak „zmień nazwę wszystkich tagów„ foo ”na„ bar ”.
Więc tldr: wybrałbym rozwiązanie z dwoma stołami. (W rzeczywistości zamierzam. Znalazłem ten artykuł, aby sprawdzić, czy istnieją uzasadnione argumenty przeciwko niemu.)