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

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

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

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

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

Ответы [ 8 ]

179 голосов
/ 02 декабря 2008

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

Что-то вроде:

Таблица: Предметы
Столбцы: Item_ID, Item_Title, Content

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

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

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

104 голосов
/ 02 декабря 2008

Вы должны прочитать сообщения в блоге Филиппа Келлера о пометке схем базы данных. Он пробует несколько и сообщает о своих результатах, как в с точки зрения простоты построения общих запросов , так и в плане производительности . Количество тегов, количество отмеченных элементов и количество тегов на элемент - все это факторы. Посты с 2005 года; С тех пор я не знаю никаких обновлений.

7 голосов
/ 03 декабря 2008

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

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

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

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

3 голосов
/ 18 августа 2015

Если вы не возражаете против использования нестандартных вещей, 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 голосов
/ 02 декабря 2008

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

1 голос
/ 02 декабря 2008

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

1 голос
/ 02 декабря 2008

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

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

0 голосов
/ 02 декабря 2008

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

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

...