"Выполнить итерации является человеческим, для рекурсивного вызова божественный" - заключенный в кавычки в 1989 в колледже.
P.S. Отправленный Woodgnome при ожидании приглашают для присоединения
Думаю, вам будет интересно это сообщение в блоге: Теги: Схемы базы данных
Проблема: вы хотите иметь схему базы данных, в которой можно пометить закладка (или сообщение в блоге, или что-то еще) с любым количеством тегов. Позже вы захотите выполнить запросы, чтобы ограничить закладки объединение или пересечение тегов. Вы также хотите исключить (скажем: минус) некоторые теги из результатов поиска.
В этом решении в схеме есть только одна таблица, она денормализована. Этот тип называется «решением MySQLicious», потому что MySQLicious импортирует данные del.icio.us в таблицу с этой структурой.
Пересечение (И) Запрос для «search + webservice + semweb»:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"
Union (OR) Запрос на «поиск | веб-сервис | semweb»:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"
Минус Запрос для «search + webservice-semweb»
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"
Scuttle организует свои данные в двух таблицах. Эта таблица scCategories является таблицей «тегов» и имеет внешний ключ к таблице «закладок».
Пересечение (И) Запрос «закладка + веб-сервис + semweb»:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3
Сначала ищутся все комбинации закладка-тег, где тег - «закладка», «веб-сервис» или «семвеб» (c.category IN ('закладка', 'веб-сервис ',' semweb ')), то учитываются только закладки, в которых был произведен поиск всех трех тегов (HAVING COUNT (b.bId) = 3).
Union (OR) Запрос для «закладка | веб-сервис | semweb»: Просто опустите предложение HAVING, и у вас будет объединение:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
Минус (Исключение) Запрос на «закладка + веб-сервис-semweb», то есть: закладка И веб-сервис, а НЕ semweb.
SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2
Если не указывать ИМЕЮЩИЙ СЧЕТ, появится запрос «закладка | веб-сервис-semweb».
Toxi придумал структуру из трех таблиц. В таблице «tagmap» закладки и теги связаны n-к-m. Каждый тег можно использовать вместе с разными закладками и наоборот. Эта схема БД также используется wordpress. Запросы такие же, как и в случае решения «спрятать».
Пересечение (И) Запрос для «закладка + веб-сервис + semweb»
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3
Union (OR) Запрос «закладка | веб-сервис | semweb»
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
Минус (Исключение) Запрос «закладка + веб-сервис-semweb», то есть: закладка И веб-сервис, А НЕ semweb.
SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2
Отсутствие ИМЕЮЩЕГО СЧЕТА приводит к запросу «закладка | веб-сервис-semweb».
Нет ничего плохого в вашем решении с тремя таблицами.
Другой вариант - ограничить количество тегов, которые могут быть применены к статье (например, 5 в SO), и добавить их непосредственно в свой article table.
Нормализация БД имеет свои достоинства и недостатки, точно так же, как жесткое объединение вещей в одну таблицу имеет свои достоинства и недостатки.
Ничто не говорит о том, что нельзя делать и то, и другое. Повторение информации идет вразрез с парадигмами реляционных БД, но если целью является производительность, возможно, придется нарушить парадигмы.
Предлагаемое решение является лучшим - если не единственным практически осуществимым - способом, который я могу придумать для решения проблемы связи "многие ко многим" между тегами и статьи. Так что я голосую «да, он по-прежнему лучший». Хотя меня бы интересовали любые альтернативы.
Если ваша база данных поддерживает индексируемые массивы (например, PostgreSQL, для пример), я бы порекомендовал полностью денормализованное решение - хранить теги как массив строк в одной таблице. Если нет, то лучшим решением будет вторичная таблица, отображающая объекты в теги. Если вам нужно сохранить дополнительную информацию для тегов, вы можете использовать отдельную таблицу тегов, но нет смысла вводить второе соединение для каждого поиска тегов.
Предложенная вами реализация трех таблиц будет работать для тегирования.
Однако переполнение стека использует другую реализацию. Они хранят теги в столбце varchar в таблице сообщений в виде обычного текста и используют полнотекстовую индексацию для извлечения сообщений, соответствующих тегам. Например, posts.tags = "передовой опыт системной маркировки алгоритмов"
. Я уверен, что Джефф где-то упоминал об этом, но я забыл где.
Однако переполнение стека использует другую реализацию. Они хранят теги в столбце varchar в таблице сообщений в виде обычного текста и используют полнотекстовую индексацию для извлечения сообщений, соответствующих тегам. Например, posts.tags = "передовой опыт системной маркировки алгоритмов"
. Я уверен, что Джефф где-то упоминал об этом, но я забыл где.
Однако переполнение стека использует другую реализацию. Они хранят теги в столбце varchar в таблице сообщений в виде обычного текста и используют полнотекстовую индексацию для извлечения сообщений, соответствующих тегам. Например, posts.tags = "передовой опыт системной маркировки алгоритмов"
. Я уверен, что Джефф где-то упоминал об этом, но я забыл где.