2013-10-28 3 views
1

На моем сайте, у меня есть система категоризации содержимого на столе T.Categories в строке MySQL выглядит какКак определить, является ли элемент «word4» строки «word1; word2; word3; word4» в строке «word4», «word5», «word6», «word7»?

category1;category2;category3;category4 

(это может быть более или менее).

С другой стороны, я позволяю своим пользователям выбирать категории, которые их интересуют. В основном, они делают свой выбор на форму и результат отображается в РНР переменной $var выглядит как

category2','category4','category5 

(и т.д.)

Запрашивая

T.Categories IN ('".$var."'))"; 

Я могу детерминированным, если содержание соответствует их интересам, только тогда, когда содержание с в соответствии с ОДНОЙ ОДНОЙ категорией.

К примеру:

  • Я фото в категории под названием «Кот»
  • Мои пользователи хотят видеть фотографии, которые принадлежат к «Cat» и категории «Собаки»
  • Мой SQL запрос выглядит SELECT * FROM T Where T.Categories IN ('".$var."'))";

практически, я говорю SGBD смотреть, если содержание T.Categories находится в списке $ вар

Он работает, когда в T.Categories есть только одна категория. «Является ли Cat IN $ var? Yes, Cat в« Cat »,« Dog ». Затем я получаю контент для пользователя (потому что Cat находится в $ var)»

Но он больше не работает, если есть более чем одной категории в T.Categories. Потому что все категории хранятся в категории category1, category2, category3, category4. К несчастью: строка «Кошка», «Лошадь, утка» не входит в «Кошку», «Собака» (MySQL ищет всю строку)

Что мне нужно, чтобы разобрать Кота, Лошадь, Утка в трех частях чтобы заставить SGBD искать каждую часть в списке $ var. Is Cat IN $ var? Да, Кот в «Кот», «Собака». Лошадь в $ var? Нет, Лошадь не в «Кошку», «Собака». Является ли утка в $ var? нет, Утка не в «Кот», «Собака». Затем я получаю контент для пользователя (потому что Cat находится в $ var).

Как я мог достичь своей цели, используя один запрос?

+0

Вам необходимо осуществить надлежащую поисковую систему; таких как сольр. Начните [здесь] (http://stackoverflow.com/questions/1893857/how-to-use-solr-with-mysql-and-php), а затем [здесь] (http://stackoverflow.com/questions/ 17907188/индексации-MySQL-в-Apache-Solr). –

+0

Может быть, немного сложно для меня в этот момент моего обучения, но определенно интересно! спасибо –

ответ

0

У вас возникла проблема с вашим дизайном. Не следует хранить категории в строке в MySQL.

Вы должны хранить категории в новой таблице, с many-to-many таблица связывающая два:

Article linked to Categories using a many-to-many table

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

SELECT A.*, L.Relevance 
FROM Article AS A 
INNER JOIN 
(
    SELECT AC.ArticleID, COUNT(AC.CategoryID) AS Relevance 
    FROM ArticleCategory AS AC 
    INNER JOIN Category AS C 
    ON AC.CategoryID = C.CategoryID 
    WHERE C.Name IN ('Cat','Dog','Donkey','Chicken') 
    GROUP BY AC.ArticleID 
) AS L 
ON A.ArticleID = L.ArticleID 
ORDER BY L.Relevance DESC, Name 

Вы можете увидеть example in SQLFiddle.

Вы также можете получить более подробную информацию здесь:

Альтернативой является использование в полной мере функции поиска текста в MySQL. Более подробная информация здесь:

+0

Благодарим за помощь –

0

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

Если вы не можете сделать это, не могли бы вы можете сгенерировать запрос выбора, как это:

SELECT * FROM T Where concat(';', T.Categories, ';') like '%;cat;%' or 
         concat(';', T.Categories, ';') like '%;dog;%' 

Если вы сохранили T.Categories с передней и задней точки с запятой не нужно будет использовать concat. Это будет означать сканирование по таблице T, т.е.индексы не могут быть использованы.

+0

Благодарим за помощь –