通常、私は Yaakov Ellis に同意しますが、この特別なケースでは別の実行可能な解決策があります。
2 つのテーブルを使用します。
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
これにはいくつかの大きな利点があります。
まず、開発がはるかに簡単になります。挿入と更新のための 3 つのテーブル ソリューションではitem
、テーブルを検索して、Tag
既にエントリがあるかどうかを確認する必要があります。次に、それらを新しいものと結合する必要があります。これは簡単な作業ではありません。
次に、クエリがより簡単になります (そしておそらくより高速になります)。実行する主なデータベース クエリは 3 つあります。すべてTags
を 1 つに出力しItem
、タグ クラウドを描画し、1 つのタグ タイトルに対してすべてのアイテムを選択します。
1 つのアイテムのすべてのタグ:
3-テーブル:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2-テーブル:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
タグクラウド:
3-テーブル:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2-テーブル:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
1 つのタグのアイテム:
3-テーブル:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2-テーブル:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
ただし、いくつかの欠点もあります。データベース内でより多くのスペースが必要になる可能性があり (これにより、より多くのディスク操作が発生し、速度が低下する可能性があります)、正規化されていないため、不整合が生じる可能性があります。
タグの性質上、タグは通常非常に小さいため、サイズの増加はそれほど大きくないため、サイズの議論はそれほど強力ではありません。タグ タイトルのクエリは、各タグを 1 回だけ含む小さなテーブルではるかに高速であると主張することができますが、これは確かに真実です。しかし、参加する必要がないことによる節約と、それらに優れたインデックスを構築できるという事実を考慮すると、これを簡単に補うことができます. もちろん、これは使用しているデータベースのサイズに大きく依存します。
矛盾の議論も少し議論の余地があります。タグはフリー テキスト フィールドであり、「すべてのタグの名前を「foo」から「bar」に変更する」などの期待される操作はありません。
だからtldr:私は2テーブルのソリューションに行きます。(実際、そうするつもりです。この記事は、それに対する有効な議論があるかどうかを確認するために見つけました。)