Обычно я соглашусь с Яаковом Эллисом, но в этом частном случае есть другое жизнеспособное решение:
Используйте две таблицы:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
У этого есть несколько основных преимуществ:
Во-первых, это значительно упрощает разработку: в решении с тремя таблицами для вставки и обновления item
вам нужно найти Tag
таблицу, чтобы увидеть, есть ли уже записи. Затем вы должны присоединить к ним новые. Это нетривиальная задача.
Затем он делает запросы проще (и, возможно, быстрее). Вам нужно выполнить три основных запроса к базе данных: вывести все Tags
для одного Item
, нарисовать облако тегов и выбрать все элементы для одного заголовка тега.
Все теги для одного элемента:
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
Элементы для одного тега:
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: я бы выбрал решение с двумя столами. (На самом деле я собираюсь. Я нашел эту статью, чтобы узнать, есть ли веские аргументы против нее.)
person
Scheintod
schedule
20.09.2013