Лучшая практика для запроса таблицы поиска
-
06-07-2019 - |
Вопрос
Я пытаюсь найти способ запроса таблицы поиска свойств.
У меня есть таблица свойств, которая содержит информацию о арендуемой недвижимости (адрес, арендная плата, залог, количество спален и т. д.), а также другую таблицу (Property_Feature), которая представляет особенности этой собственности (бассейн, кондиционер, прачечная и т.д.). сайт и т. д.). Сами элементы определены в еще одной таблице с меткой Feature.
Property
pid - primary key
other property details
Feature
fid - primary key
name
value
Property_Feature
id - primary key
pid - foreign key (Property)
fid - foreign key (Feature)
Допустим, кто-то хочет найти недвижимость, в которой есть кондиционер, бассейн и прачечная. Как запросить в таблице Property_Feature несколько объектов для одного и того же свойства, если каждая строка представляет только один объект? Как будет выглядеть SQL-запрос? Это возможно? Есть ли лучшее решение?
Спасибо за помощь и понимание.
Решение
С точки зрения дизайна базы данных, ваш правильный способ сделать это. Это правильно нормализовано.
Для запроса я просто использовал бы существует, например:
select * from Property
where
exists (select * from Property_Feature where pid = property.pid and fid = 'key_air_conditioning')
and
exists (select * from Property_Feature where pid = property.pid and fid = 'key_pool')
Где key_air_conditioning и key_pool, очевидно, являются ключами для этих функций.
Производительность будет хорошей даже для больших баз данных.
Другие советы
Вот запрос, который найдет все свойства с пулом:
select
p.*
from
property p
inner join property_feature pf on
p.pid = pf.pid
inner join feature f on
pf.fid = f.fid
where
f.name = 'Pool'
Я использую внутренние объединения вместо EXISTS
, так как это происходит немного быстрее.
Вы также можете сделать что-то вроде этого:
SELECT *
FROM Property p
WHERE 3 =
( SELECT COUNT(*)
FROM Property_Feature pf
, Feature f
WHERE pf.pid = p.pid
AND pf.fid = f.fid
AND f.name in ('air conditioning', 'pool', 'laundry on-site')
);
Очевидно, что если ваш пользовательский интерфейс захватывает фиды элементов, когда пользователь их выбирает, вы можете отказаться от объединения с функцией и ограничиться непосредственно фидом. Ваш пользовательский интерфейс будет знать, какое количество объектов было выбрано, поэтому определите значение для «3». выше тривиально.
Сравните это с точки зрения производительности с конструкцией tekBlues выше; в зависимости от вашего распределения данных любой из них может быть более быстрым запросом.