2009-09-03 3 views
1

У меня есть базы данных MySQL с 3 таблицами:Как найти дополнительные теги?

  1. Основной таблица записей, называемых «следами» (как в музыке)
  2. таблицу тегов называемых «метка»
  3. Объединение таблицы два называемых «метками»

Таблица тэгов - это в основном список жанров, который заранее определен. После этого трек может иметь 1 или более тегов (через таблицу соединений).

Идея состоит в том, что пользователь проверяет жанры (теги), для которых он или она хочет найти дорожки. Но мне также хотелось бы, чтобы интерфейс отражал те теги, которые больше не «полезны», т. Е. Теги, которые дополняют выбранные в настоящий момент.

Редактировать: Я пропустил то, что мне нужно найти теги, которые дополняют выбранный набор тегов. См. Мой комментарий ниже.

Пример: пользователь выбирает теги «рок» и «поп» и отображается список дорожек, соответствующих «рок» + «поп». Но предположим, что в базе данных нет треков, которые также матч «джаз». В этом случае я хотел бы отключить тег «jazz» в интерфейсе, потому что «rock» + «pop» + «jazz» дал бы нулевые результаты.

Есть ли умный способ сделать это с MySQL?

+0

Я добавил еще один вариант, это действительно просто передел первого, но, возможно, он не убьет вашего клиента. – scottm

+0

Друг указал на что-то, что усложняет дело: запрос должен найти возможные «последовательные» теги, так сказать. То есть если вы ищете метки 1 и/или 3, вы найдете треки, которые имеют один или оба. Все идет нормально. Но ниже будут указаны, есть ли треки с тегами 1 & X, _or_ tag 3 & X, но на самом деле нужно посмотреть, есть ли треки с тегами 1 _and_ 3 _and_ X. И это делает все очень сложным, как я могу сказать – Flambino

ответ

0

в конечном итоге делает это:

  • Когда трек помечен, его идентификаторы тегов сцепляются (в указанном порядке) и добавляли к справочной таблице 1 столбцов (и, конечно, также оснащениям). Например. «, 1,2,4,6,9» добавляется к поиску (есть причина для запятых переднего/заднего)
  • Когда теги выбраны во время поиска, они аналогичным образом объединены и используются в LIKE положение, которое выбирает все конкатенации из таблицы поиска, которые содержат эти идентификаторы тегов
  • найденные конкатенации затем обрабатываются, чтобы получить все идентификаторы, которые они содержат
  • Какой бы ни идентификаторы не в результирующий список, таким образом, дополняют выбранных
1
select 
    tagid 
from 
    taggings 
where 
    trackid in ([list of, or subquery for your selected tracks]) 

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

+0

Я думаю, что дело в том, чтобы включить элементы управления и позволить пользователю щелкнуть их. – scottm

+0

Ну, да, пользователь должен иметь возможность щелкнуть тегами-элементами управления, которые «имеют смысл». Насколько эффективнее всего отключить все, а затем включить некоторые или включить все, а затем отключить некоторые, я не знаю. В зависимости от того, какой наиболее эффективный запрос; теги используются вместе с текущими или найдите те, которые не используются с текущими. – Flambino

+0

«Не в» запросы, как известно, неэффективны, так как они обычно требуют полного сканирования таблицы, тогда как «В» требуется только поиск до первого попадания. «Не в» легче читать и понимать, но менее эффективно. Как вы обрабатываете обработку этих данных после извлечения, я не могу сказать, не зная больше о вашем дизайне интерфейса. – krdluzni

0

Это, вероятно, является не самым эффективным:

SELECT 
    TagId --to disable 
FROM Tags 
WHERE TagId NOT IN(
    SELECT Distinct TagId FROM Taggings WHERE TrackId IN (
     SELECT TrackId FROM Taggings WHERE TagId in (1, 2) 
    ) 
) 
  1. Получить все дорожки, соответствующие выбранным в данный момент тегов.
  2. Возьмите все теги, присвоенные эти треки
  3. Отключить теги не в этом списке

Редактировать
Что об этом:

SELECT 
    DISTINCT TagId 
FROM 
    Taggings 
GROUP BY 
    TagId, 
    TrackId HAVING TrackId IN (
     SELECT 
      TrackId 
     FROM 
      Taggings 
     WHERE 
     TagId in (1, 2) 
    ) 

Это должно вернуть все теги, которые должны быть включенным.

+0

Хммм .. что разбил мой MySQL-клиент :-) Проблема в том, что у меня есть тысячи треков, и мне нужен интерфейс, чтобы быть очень отзывчивым. Хотя ваш ответ, вероятно, сработает, кажется, это слишком грубая сила, так сказать. Я думаю, что должно быть возможно найти теги-теги, которые используются вместе, просто из-short-list выбранных тегов, а не список тысяч track_ids. – Flambino

+0

Да, я подумал, что это будет немного грубо. Я не думаю, что вы сможете сделать это только с тегами. Я думаю, вы должны иметь треки, чтобы узнать, каковы остальные возможности тегов. – scottm

+0

Да, ты, наверное, прав. Но теперь я собираюсь добавить еще одну таблицу с различными комбинациями тегов для более быстрого поиска. Я позволю этому вопросу сидеть здесь некоторое время, хотя и посмотреть, что произойдет. Но спасибо за вход до сих пор! – Flambino

0

У вас есть контроль над добавлением тегов к трекам? Если вы можете подключиться к этому, вы можете создать дополнительные метаданные.

По существу, многие-ко-многим соединяются между тегами. Каждый раз, когда вы добавляете тег, вы добавляете запись в эту таблицу соединений, содержащую пару old-tag/new-tag (с нижним идентификатором в качестве первого значения для уменьшения дублирования) для каждого из старых тегов на этом треке. IIRC, есть способ настроить таблицу, чтобы игнорировать дубликаты вставок, а не бросать ошибки.Вам также придется управлять этой таблицей во время удаления тегов, что будет более трудоемким, но это, вероятно, редкое событие.

С выше на месте у вас есть простой запрос, чтобы идентифицировать метки, которые до сих пор актуальны:

select 
    tag_a 
from 
    related_tags 
where 
    tag_b in ([tags_already_in_search]) 
union 
select 
    tag_b 
from 
    related_tags 
where 
    tag_a in([tags_already_in_search]) 

Это решение существенно смещает часть времени обработки в момент времени, когда добавлены теги и удалены.

+0

Интересно! Я попробую это. И да, я думал о создании таблицы поиска из двух столбцов, точно так же, как вы описываете, именно потому, что она переместила загрузку сервера в другой момент времени и потому что я полностью контролирую, когда теги добавляются/удаляются/изменяются , – Flambino

Смежные вопросы