4

У меня есть база данных PostgreSQL с некоторыми схемами, как показано ниже:Выберите (восстановить) все записи из нескольких схем с использованием Postgres

My_Database 
|-> Schemas 
    |-> AccountA 
    |-> AccountB 
    |-> AccountC 
    |-> AccountD 
    |-> AccountE 
      . 
      . 
      . 
    |-> AccountZ 

Все схемы имеет таблицу с именем product, который имеет столбец под названием title. Я хотел бы знать, возможно ли выполнить оператор select для извлечения всех записей из всех схем с определенным условным.

Единственный способ, которым я нашел до сих пор, - запустить учетную запись запроса по учетной записи, как показано ниже.

SET search_path TO AccountA; 

SELECT title FROM product WHERE title ILIKE '%test%'; 

Schemas создаются динамически, так что я не знаю их имен или сколько из них существует.

+2

без использования системных таблиц, чтобы получить список схем, принявшего эту таблицу, а затем с помощью динамического SQL, чтобы создать союз между всеми запросами. Я не думаю, что это можно сделать ... и это, конечно, не будет быстрым. – xQbert

+0

Чтобы завершить это, вам понадобится динамический SQL, и это будет непросто сделать.Эта схема ужасна, любая воля для нормализации этого? Одна таблица со всеми учетными записями намного лучше, чем схема для каждой учетной записи ... до такой степени, что вы, похоже, сильно искалечены этой настройкой. – Twelfth

+0

Обратите внимание, что схема представляет собой базу данных, а не таблицу. У вас есть одна схема (Моя база данных) с большим количеством таблиц. –

ответ

7

С inheritance, как @Denis mentioned, это было бы очень просто. Работает и для Postgres 8.4. Обязательно рассмотрите limitations.

В принципе, вы бы мастер-таблицу, я полагаю, в главной схеме:

CREATE TABLE master.product (title text); 

И все другие таблицы в различных схемах наследуют от него, возможно, добавляя больше местных колонок:

CREATE TABLE a.product (product_id serial PRIMARY KEY, col2 text) 
INHERITS (master.product); 

CREATE TABLE b.product (product_id serial PRIMARY KEY, col2 text, col3 text) 
INHERITS (master.product); 

и т.д.

Таблицы не должны иметь одно и то же имя или схему.
Тогда вы можете запрос все таблицы в одном махом:

SELECT title, tableoid::regclass::text AS source 
FROM master.product 
WHERE title ILIKE '%test%'; 

tableoid::regclass::text?
Это удобный способ рассказать об источнике каждой строки. Реквизиты:

SQL Fiddle.

+0

обязательно измените контекст вопроса в соответствии с ответом, и все будет работать. Используя существующий дизайн, представленный ... не так много ... Я поддерживаю свой оригинальный комментарий. без динамических sql союзов, хотя неопределенное количество таблиц продуктов это невозможно. Измените дизайн на использование OOP и наследование или используйте разделение в других dbs (я думаю, postgresql делает это, хотя наследование), и да, это можно сделать. Возможно, я построил коробку, где ее не было, возможно, вы уничтожили ящик, в котором он существовал. Только автор может сказать нам. – xQbert

+0

Эрвин, приятное предложение! На ваш взгляд, было бы лучше использовать наследование или динамический SQL? Мое главное - создать базу данных, удобную для управления и хорошую производительность. –

+1

@MarcioSimao: Нет ничего в вопросе, который противоречил бы наследованию (который имеет некоторые ограничения, прочитайте руководство!). Пока это не так, мое предложение явно проще, быстрее и безопаснее, чем динамический SQL, который является более гибким. –

1

Вы в основном хотите союз все:

SELECT title FROM AccountA.product WHERE title ILIKE '%test%' 
UNION ALL 
SELECT title FROM AccountB.product WHERE title ILIKE '%test%' 
UNION ALL 
...; 

Вы можете сделать это автоматически, используя динамический SQL и каталог, чтобы найти все схемы AccountXYZ, которые имеют таблицу продуктов.

В качестве альтернативы, создайте схему AllAccounts с аналогичными таблицами, как в отдельных схемах, и используйте наследование таблицы.

Обратите внимание, что ни одна из них не сообщит вам, с какой схемы данные, однако. В первом случае это достаточно легко добавить; не так много в последнем, если вы не добавите дополнительную колонку.

+0

Возможно, вас заинтересует метод определения исходной таблицы. –

+2

@ErwinBrandstetter: О, бормоча. Ты слишком хорош в этом. +1 к вам. ;-) –

Смежные вопросы