Поиск по нескольким таблицам (лучшие практики) - PullRequest
2 голосов
/ 29 июня 2009

У меня есть приложение для управления имуществом, состоящее из таблиц:

tenants
landlords
units
properties
vendors-contacts

По сути, я хочу, чтобы одно поле поиска выполняло поиск по всем, а не по какой категории я искал. Будет ли это приемлемым решением (по технологии?)

Будет ли в конечном итоге поиск по 5 таблицам нормальным и не замедлит работу сервера? Какой лучший способ сделать это?

Использование PostgreSQL

Ответы [ 4 ]

7 голосов
/ 29 июня 2009

Почему бы не создать представление, представляющее собой объединение таблиц, объединяющих столбцы, по которым вы хотите выполнить поиск, в одну, а затем выполнить поиск по этому агрегированному столбцу?

Вы могли бы сделать что-то вроде этого:

select 'tenants:' + ltrim(str(t.Id)), <shared fields> from Tenants as t union
select 'landlords:' + ltrim(str(l.Id)), <shared fields> from Tenants as l union
...

Это требует, чтобы некоторая логика была встроена из запросов клиента; он должен знать, как изготовить ключ, который он ищет, чтобы искать в одном поле.

Тем не менее, вероятно, будет лучше, если у вас будет отдельный столбец, который содержит значение типа (например, арендодатель, арендатор), а затем фильтр по типу и идентификатору, поскольку он будет в вычислительном отношении менее дорогим (и может оптимизируйся лучше).

4 голосов
/ 29 июня 2009

Вы хотите использовать встроенный полнотекстовый поиск или отдельный продукт, такой как Lucene . Это оптимизировано для неструктурированных поисков по разнородным данным.

Также не забывайте, что нормальные индексы нельзя использовать для something LIKE '%...%'. Использование полнотекстового поискового движка также позволит выполнять эффективный поиск по подстроке.

3 голосов
/ 29 июня 2009

Я бы предложил для этого использовать специализированный инструмент полнотекстовой индексации, такой как Lucene. Вероятно, будет легче приступить к работе, и результат будет более быстрым и более функциональным. Полнотекстовые индексы Postgres будут полезны, если вам также нужна возможность структурированного поиска или важна транзакционность вашего поискового индекса.

Если вы хотите реализовать это в базе данных, может сработать что-то вроде следующей схемы, при условии, что вы используете суррогатные ключи:

  1. для каждой таблицы с возможностью поиска создайте представление, в котором есть столбец первичного ключа этой таблицы, имя таблицы и объединение всех полей с возможностью поиска в этой таблице.
  2. создать функциональный индекс GIN или GiST на основе поверх to_tsvector () точно такой же конкатенации.
  3. создайте UNION ALL для всех видов, чтобы создать вид с возможностью поиска.

После этого вы можете выполнить поиск следующим образом:

SELECT id, table_name, ts_rank_cd(body, query) AS rank
    FROM search_view, to_tsquery('search&words') query
    WHERE query @@ body
    ORDER BY rank DESC
    LIMIT 10;
1 голос
/ 29 июня 2009

С тобой все должно быть в порядке, и действительно нет другого хорошего (простого) способа сделать это. Просто убедитесь, что поля, по которым вы ищете, правильно проиндексированы.

...