Скажу сразу, дальше будет то еще извращение, но что поделать работа такая… Есть таблица с товарами, меня интересует столбец название товара (name_product), и есть таблица с характеристиками товара (feature), простой пример: товар «Кирпич», характеристики «красный»,«желтый», «опт» и т.д.
Необходимо написать поиск по этому делу… с возможностью релевантности, т.е. если запросили кирпич красный то он должен выдать кирпич с характеристикой первыми…
У меня одна только мысль, денормализировать все в одну таблицу и в ней искать, но тут возникает сомнение, если товар 100, а характеристик 100000 и нашли только в одном товаре, то зачем перебирать все характеристики. Может можно как то в запросе сначала искать по товару, если в нем нашлось то выдавать, если нет то искать везде.
Придумал что то типа этого (но не знаю с точки зрения ресурсов):
SELECT CONCAT( `t1`.`name_goods`, IF( `t2`.`feature` != "", CONCAT( " ", `t2`.`feature` ), "" ) ) AS `name_goods`,
MATCH (
`name_goods`
)
AGAINST (
«кирпич утолщенный облицовочный пустотелый»
) AS relevance
FROM `im_goods` AS `t1`
INNER JOIN `im_records` AS `t2` ON `t2`.`id_goods` = `t1`.`id_goods`
WHERE `name_goods` LIKE "%кирпич%утолщенный%"
ORDER BY `relevance` DESC, `name_goods`
Если в данном случае за релевантность сойдет понятие «количество совпавших названий характеристик из запроса», то можно сделать что-то типа этого:
SELECT…
FROM products
WHERE (name_product = 'кирпич' OR name_product = 'красный')
ORDER BY (
SELECT count(*) FROM features WHERE product.id=features.p_id AND (name_feature = 'кирпич' OR name_feature = 'красный')
Правда работать это будет, наверное, не очень быстро. Поэтому, мне кажется, лучше при изменении характеристик добавлять их названия в поле товара и искать текстовым поиском
Если нужна релевантность и полнотекстовый поиск по характеристикам — без денормализации не обойтись, MATCH можно выполнять только по существующему индексу. В качестве тормозного хака можно использовать что-то вроде
SELECT items.name,GROUP_CONCAT(features.name),COUNT(features.name)
FROM items LEFT JOIN features
ON items.id=features.item_id
AND (
features.name='кирпич' OR features.name='утолщенный'
OR features.name='облицовочный' OR features.name='пустотелый'
)
В случае большой базы, лучше всё же прикрутить сторонний поисковый движок вроде sphinx-а.