поиск по ключевым словам mysql по нескольким столбцам
-
12-09-2019 - |
Вопрос
Различные варианты этого вопроса задавались здесь раньше, но я решил попробовать еще раз.
У меня была ужасная компоновка базы данных.Единый объект (виджет) был разделен на две таблицы:
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.