Нормализация БД или удобство запросов?
Подскажите пожалуйста, например у нас есть сайт с описанием автомобилей. Возьмём один из них: описание Porsche 911 GT2 992. У нас будут повторяться и марка и модель и номер кузова, поэтому их мы выведем в отдельные таблицы, как рекомендовано это делать, и в конце концов из БД мы сможем получить, что-то такое:
Porsche | 911 | GT2 | 992 |описание
А теперь представим, что пользователь ищет описание для этого автомобиля через наш поиск.
И отправляет через поиск “Porsche 911”
У нас нет ни в одной ячейки БД «porsche 911» нам нужно вначале обьединить 4 колонки и уже потом делать поиск. Но это как-то не изящно для 2021 года. Если запихать марку, модель, номер кузова в одну ячейку - то это как-то не правильно с точки зрения нормализации, да и фильтровать например по марке или кузову станет сложнее. Как быть? Есть 3-й сценарий? Полнотекстовый поиск? Или это дорого для такого случая?
Ответы (1 шт):
Объединять все в одну ячейку не стоит, т.к. это не будет работать, если пользователь скажем введет не "Porsche 911", а "911 Porsche". Наверняка, вы захотите, чтоб в этом случае тоже находился результат.
И тут без полнотекстового поиска не обойтись. Можно использовать встроенный или внешний (типа solr или elasticsearch).
Для встроенного это может выглядеть так:
create table auto (manufacturer text, model text, body text);
insert into auto values ('Porsche', '911 GT', '992');
=> SELECT * from auto where to_tsvector('english', manufacturer || ' ' || model || ' ' || body) @@ to_tsquery(E'\'Porsche 992\'');
manufacturer | model | body
--------------+--------+------
Porsche | 911 GT | 992
(1 row)
можно создать индекс, для того чтобы данные парсились один раз при вставке
create index auto_full_text on auto
using gin(to_tsvector('english', manufacturer || ' ' || model || ' ' || body));