2009-07-17 2 views
1

Я работаю над небольшим программным обеспечением для блогов, и я хочу, чтобы к сообщению прикреплялись теги. Каждое сообщение может иметь между 0 и бесконечными тегами, и мне интересно, возможно ли это сделать, не связывая таблицы?Join-Free Структура таблицы для тегов

Поскольку количество тегов не ограничено, я не могу просто создать n полей (Tag1 to TagN), поэтому другой подход (который, по-видимому, является одним из StackOverflow), заключается в использовании одного большого текстового поля и разделителя, т.е. "<Tag1> <Tag2> <Tag3>".

Проблема: Если я хочу отображать все сообщения с тегом, мне нужно будет использовать инструкцию «Like»% Tag2 >% », и это может AFAIK не использовать индексы, требующие полной таблицы сканирования.

Есть ли подходящий способ решить эту проблему?

Примечание: Я знаю, что отдельный стол Tag-Link предлагает преимущества и что я не должен беспокоиться о производительности без измерения и т. Д. Меня больше интересуют различные способы разработки системы.

+0

В конце концов, Нико прав. Мне понравилась идея Full-Text индексации Дэвида (+1 к этому), но в конце концов это не очень практично. –

ответ

3

Отдельная таблица тегов - это действительно единственный способ пойти сюда. Это единственный способ разрешить бесконечное количество тегов.

6

Желание сделать это без присоединений поражает меня как преждевременную оптимизацию. Если к этой таблице часто обращаются, ее страницы, скорее всего, будут в памяти, и вы не будете получать от нее штрафы ввода-вывода, а планы для запросов, к которым он обращается, скорее всего будут кэшироваться.

+1

Правильное индексирование также способствовало бы уменьшению любого штрафа за соединение. –

0

Если вы используете SQL Server, вы можете использовать одно текстовое поле (кажется, подходит) (varchar (max)) и полнотекстовое индексирование. Затем просто выполните полнотекстовый поиск тега, который вы ищете.

2

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

Posts: 
PostID | PostTitle | PostBody   | PostAuthor 
--------+--------------+-------------------+------------- 
1146044 | Join-Free... | I'm working on... | Michael Stum 

Tags: 
TagID | TagName 
------+------------- 
1  | Archetecture 

PostTags: 
PostID | TagID 
--------+------ 
1146044 | 1 

Тогда Вы можете добавить столбцы для оптимизации запросов. Если бы это был я, я бы просто оставил только таблицы и Tags и добавил дополнительную информацию в таблицу соединений PostTags. Конечно, то, что я добавляю может зависеть немного о запросах я намерен работать, но, вероятно, я бы по крайней мере, добавить Posts.PostTitle, Posts.PostAuthor и Tags.TagName, так что мне нужно работать только два запроса для показа сообщения в блоге,

SELECT * FROM `Posts` WHERE `Posts`.`PostID` = $1 
SELECT * FROM `PostTags` WHERE `PostTags`.`PostID` = $1 

И суммируя все сообщения для данного тега требуется даже меньше,

SELECT * FROM `PostTags` WHERE `PostTags`.`TagName` = $1 

Очевидно, что недостаток денормализацию является то, что это означает, что вы должны сделать немного больше работы, чтобы сохранить денормализованные таблицы до настоящего времени. Типичный способ борьбы с этим состоит в том, чтобы поместить некоторые проверки здравомыслия в ваш код, который обнаруживает, что денормализованный запрос не синхронизирован, сравнивая его с другой информацией, доступной ему. Такая проверка может пойти в приведенном выше примере, сравнив заголовки сообщений в результирующем наборе PostTags против заголовка в результате результата Posts. Это не вызывает дополнительный запрос. Если есть несоответствие, программа может уведомить администратора, то есть путем регистрации несогласованности или отправки электронной почты.

Крепление легко (но дорогостоящим с точки зрения нагрузки на сервер), выкидывать дополнительные столбцы и восстанавливать их из нормализованных таблиц. Очевидно, вы не должны этого делать, пока не найдете причину синхронизации базы данных.