Каков наиболее эффективный способ хранения тегов в базе данных?

139

Я внедряю на своем веб-сайте систему тегов, аналогичную той, что используется в stackoverflow, мой вопрос - каков наиболее эффективный способ хранения тегов, чтобы их можно было искать и фильтровать?

Моя идея такая:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Это слишком медленно? Есть ли способ лучше?

Логан Серман
источник
2
Ранее заданный вопрос: stackoverflow.com/questions/20856/…
DrBloodmoney 02
2
По состоянию на 2016 год используйте Solr или Elasticsearch
Чарльз Л.

Ответы:

193

У одного предмета будет много тегов. И один тег будет принадлежать многим предметам. Это означает, что вам, возможно, понадобится промежуточная таблица, чтобы преодолеть препятствие «многие ко многим».

Что-то типа:

Таблица: Элементы
Столбцы: Item_ID, Item_Title, Content

Таблица:
Столбцы тегов : Tag_ID, Tag_Title

Таблица: Items_Tags
Столбцы: Item_ID, Tag_ID

Может случиться так, что ваше веб-приложение очень популярно и в будущем его нужно будет изменить, но слишком рано мутить воду бессмысленно.

Саймон Скарф
источник
Связано: stackoverflow.com/questions/20856/…
Cherian
если есть что-то вроде tagGroup, как с этим обращаться, например, теги сгруппированы по категориям, например: Языки программирования: c #, vb, pearl. ОС: windows7, dos, linux и т. Д.
Thunder
4
@Thunder: предполагая, что один тег может принадлежать только к одной категории, я бы создал таблицу TagCategory, состоящую из category_id и category_name. Оттуда я бы добавил поле category_id в таблицу Tags и выполнил соединение с ним.
Саймон Скарф,
8

На самом деле я считаю, что денормализация таблицы тегов может быть лучшим способом продвижения вперед, в зависимости от масштаба.

Таким образом, в таблице тегов просто есть tagid, itemid, tagname.

Вы получите повторяющиеся тэги, но это значительно упростит добавление / удаление / редактирование тэгов для определенных элементов. Вам не нужно создавать новый тег, удалять выделение старого и перераспределять новый, вы просто редактируете тег.

Для отображения списка тегов вы просто используете DISTINCT или GROUP BY, и, конечно же, вы можете легко подсчитать, сколько раз используется тег.

Нил Барнуэлл
источник
4

Если вы не против использования нестандартных вещей, Postgres версии 9.4 и выше имеет возможность хранить запись типа текстового массива JSON.

Ваша схема будет:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Для получения дополнительной информации см. Этот отличный пост Джоша Беркуса: http://www.databasesoup.com/2015/01/tag-all-things.html

Существует больше различных вариантов, которые тщательно сравниваются по производительности, и тот, который предложен выше, в целом является лучшим.

Дмитрий Шведов
источник
2

Вы не можете говорить о медлительности, основываясь на данных, которые вы предоставили в вопросе. И я не думаю, что вам следует слишком сильно беспокоиться о производительности на этом этапе разработки. Это называется преждевременной оптимизацией .

Однако я бы посоветовал вам включить столбец Tag_ID в таблицу тегов. Обычно рекомендуется, чтобы в каждой таблице был столбец идентификатора.

Rockcoder
источник
2

Я бы предложил использовать третью промежуточную таблицу для хранения тегов <=> ассоциаций элементов, поскольку у нас есть отношения «многие ко многим» между тегами и элементами, т.е. один элемент может быть связан с несколькими тегами, а один тег может быть связан с несколькими элементами. HTH, клапан.

Валентин Васильев
источник
1

Если пространство будет проблемой, создайте третью таблицу тегов (Tag_Id, Title) для хранения текста для тега, а затем измените таблицу тегов на (Tag_Id, Item_Id). Эти два значения также должны обеспечивать уникальный составной первичный ключ.

Адам Поуп
источник
0

Элементы должны иметь поле «ID», а теги должны иметь поле «ID» (первичный ключ, кластеризованный).

Затем создайте промежуточную таблицу ItemID / TagID и поместите туда « Perfect Index ».

Тимоти Хури
источник