поиск по ключевым словам mysql по нескольким столбцам

StackOverflow https://stackoverflow.com/questions/1840580

Вопрос

Различные варианты этого вопроса задавались здесь раньше, но я решил попробовать еще раз.

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

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%'.Это дало бы мне все экземпляры виджетов черного цвета, или производства blackwell industries, или чего-то еще.Я бы даже точно знал, какое поле соответствует, и мог бы показать это своему пользователю.

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

Это было полезно?

Решение

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

С твоим телом все в порядке. 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;

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

Другие советы

Вы можете включить часть 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 на стороне сценария.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top