поиск по ключевым словам mysql по нескольким столбцам - PullRequest
1 голос
/ 03 декабря 2009

Здесь уже задавались различные варианты этого вопроса, но я решил дать ему еще один шанс.

У меня была ужасная структура базы данных. Один объект (виджет) был разбит на две таблицы:

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment)

CREATE TABLE widget_data ( widget_id int(10), field ENUM('name','size','color','brand'), data TEXT)

это было не так идеально. Если я хотел найти виджеты с определенным именем, цветом и маркой, мне нужно было выполнить трехстороннее соединение в таблице widget_data. поэтому я преобразовал в разумный тип таблицы:

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment, name VARCHAR(32),size INT(3),color VARCHAR(16), brand VARCHAR(32))

Это делает большинство запросов намного лучше. Но это затрудняет поиск. Раньше было так, что если бы я хотел искать виджеты, скажем, «% black%», я бы просто SELECT * FROM widget_data WHERE data LIKE '%black%'. Это дало бы мне все экземпляры виджетов, которые имеют черный цвет, или сделаны из отраслей блэквелла, или чего-то еще. Я бы даже точно знал, какое поле соответствует, и мог бы показать это моему пользователю.

как мне выполнить подобный поиск, используя новый макет таблицы? Я, конечно, мог бы сделать WHERE name LIKE '%black%' OR size LIKE '%black%'..., но это кажется неуклюжим, и я до сих пор не знаю, какие поля совпадают. Я мог бы выполнить отдельный запрос для каждого столбца, по которому я хочу сопоставить, что дало бы мне все совпадения и их соответствие, но это было бы ударом по производительности. есть идеи?

Ответы [ 3 ]

4 голосов
/ 03 декабря 2009

У вас есть два противоречивых требования. Вы хотите искать, как будто все ваши данные находятся в одном поле, но вы также хотите определить, какое конкретное поле было найдено.

Нет ничего плохого в вашем WHERE name LIKE '%black%' OR size LIKE '%black%'... выражении. Это совершенно правильный поиск в таблице, как вы ее определили. Почему бы просто не проверить результаты в коде, чтобы увидеть, какой из них соответствует? Это минимальные накладные расходы.

Если вам нужен более чистый синтаксис для вашего SQL, вы можете создать представление для таблицы, добавив дополнительное поле, которое состоит из объединения других полей:

CREATE VIEW extra_widget_data AS
  SELECT (name, size, color, brand,
          CONCAT(name, size, color, brand) as all_fields)
  FROM widget_data;

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

2 голосов
/ 03 декабря 2009

Вы можете включить часть выражения WHERE в выбранные столбцы. Например:

SELECT 
  *, 
  (name LIKE '%black%') AS name_matched,
  (size LIKE '%black%') AS size_matched
FROM widget_data 
WHERE name LIKE '%black%' OR size LIKE '%black%'...

Затем проверьте значение name_matched на стороне скрипта.

Не уверен, как это повлияет на производительность. Не стесняйтесь проверить его перед началом производства

0 голосов
/ 03 декабря 2009

Возможно, вы захотите изучить возможности полнотекстового поиска MySQL, это позволяет сопоставлять несколько столбцов типа varchar.

http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...