Обычно я согласен с Яковом Ellis, но в этом особом случае существует еще один жизнеспособное решение:
Используйте две таблицы:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
Это имеет ряд существенных преимуществ:
Сначала это делает разработка намного проще: в трехэтажном решении для вставки и обновления item
вам нужно найти таблицу Tag
, чтобы увидеть, есть ли уже записи. Тогда вы должны присоединиться к ним с новыми. Это не тривиальная задача.
Затем он делает запросы проще (и, возможно, быстрее). Будут три основных запроса к базе данных, которые вы сделаете: Выведите все Tags
за один Item
, нарисуйте облако тегов и выберите все элементы для одного заголовка тега.
Теги для одного пункта:
3-Table:
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
Tag-Cloud:
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
Элементы для одной категории:
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
Но есть и некоторые недостатки: он может занимать больше места в базе данных (что может привести к большему количеству операций с дисками, которое медленнее), и это не нормализовано, что может привести к несоответствиям.
Аргумент размера не настолько силен, потому что сама природа тегов заключается в том, что они обычно довольно маленькие, поэтому увеличение размера не является большим. Можно утверждать, что запрос названия тега намного быстрее в маленькой таблице, которая содержит каждый тег только один раз, и это, безусловно, верно. Но принимая во внимание экономию за то, что вы не должны присоединиться, и тот факт, что вы можете построить хороший индекс, может легко компенсировать это. Это, конечно, сильно зависит от размера используемой базы данных.
Аргумент несогласованности тоже немного спор. Теги - это бесплатные текстовые поля, и нет ожидаемой операции, например, «переименовать все теги» foo »в« bar ».
Итак, tldr: Я бы выбрал решение с двумя столами. (. На самом деле я собираюсь я нашел эту статью, чтобы увидеть, если есть веские аргументы против него.)
Хорошо, это вопрос # 20856, (почти) тот же вопрос # 48475 спросил по крайней мере две недели после того, как этот вопрос был задан. – dlamblin 2008-10-07 16:02:38
Еще один интересный вопрос: «Как SO реализует теги?» – Mostafa 2011-11-28 19:19:35
Еще один интересный вопрос: «Не могли бы вы интернационализировать их, и если да, то как?» – DanMan 2013-12-03 11:14:51