Я собираюсь предположить, что ответ будет «нет» на основании приведенного ниже сообщения об ошибке (и этот результат Google), но есть ли способ выполнить запрос между базами данных с помощью PostgreSQL?
databaseA=# select * from databaseB.public.someTableName;
ERROR: cross-database references are not implemented:
"databaseB.public.someTableName"
Я работаю с некоторыми данными, которые разделены между двумя базами данных, хотя данные действительно разделяются между ними (столбцы идентификаторов пользователей в одной базе данных берутся из таблицы users в другой базе данных). Понятия не имею, почему это две отдельные базы данных вместо схемы, но c'est la vie ...


Я столкнулся с этим до того, как пришел к такому же выводу о перекрестных запросах к базе данных, что и вы. В конечном итоге я использовал схемы для разделения табличного пространства таким образом, чтобы можно было сгруппировать таблицы, но при этом запрашивать их все.
Примечание: как предполагал исходный запросчик, если вы настраиваете две базы данных на одном компьютере, вы, вероятно, захотите вместо этого создать две схемы - в этом случае вам не нужно ничего особенного для запроса по ним.
postgres_fdwИспользуйте postgres_fdw (оболочку сторонних данных) для подключения к таблицам в любой базе данных Postgres - локальной или удаленной.
Обратите внимание, что есть сторонние оболочки данных для других популярных источников данных. В настоящее время только postgres_fdw и file_fdw являются частью официального дистрибутива Postgres.
Эти старые версии больше не поддерживаются, но если вам нужно сделать это при установке Postgres до 2013 года, есть функция под названием dblink.
Я никогда не использовал его, но он поддерживается и распространяется вместе с остальной частью PostgreSQL. Если вы используете версию PostgreSQL, которая поставляется с вашим дистрибутивом Linux, вам может потребоваться установить пакет под названием postgresql-contrib.
Необходимо установить postgresql-contrib до dblink? Или postgresql-contrib включает dblink? И тогда запрос OP будет работать, или вам нужно запросить его по-другому?
Из того, что я могу прочитать, dblink не обрабатывает случай, когда вам нужен запрос, охватывающий две базы данных.
Если производительность важна и большинство запросов доступны только для чтения, я бы предложил реплицировать данные в другую базу данных. Хотя это кажется ненужным дублированием данных, оно может помочь, если требуются индексы.
Это можно сделать с помощью простых триггеров вставки, которые, в свою очередь, вызывают dblink для обновления другой копии. Есть также полноценные варианты репликации (например, Slony), но это не по теме.
Да, вы можете использовать DBlink (только postgresql) и DBI-Link (разрешает внешние запросы к базе данных) и TDS_LInk, который позволяет запускать запросы к серверу MS SQL.
Раньше я с большим успехом использовал DB-Link и TDS-link.
Just to add a bit more information.
There is no way to query a database other than the current one. Because PostgreSQL loads database-specific system catalogs, it is uncertain how a cross-database query should even behave.
contrib/dblink allows cross-database queries using function calls. Of course, a client can also make simultaneous connections to different databases and merge the results on the client side.
Эта дополнительная информация может вводить в заблуждение и может оттолкнуть пользователей от использования вышеуказанного решения.
dblink executes a query (usually a SELECT, but it can be any SQL statement that returns rows) in a remote database.
When two text arguments are given, the first one is first looked up as a persistent connection's name; if found, the command is executed on that connection. If not found, the first argument is treated as a connection info string as for dblink_connect, and the indicated connection is made just for the duration of this command.
один из хороших примеров:
SELECT *
FROM table1 tb1
LEFT JOIN (
SELECT *
FROM dblink('dbname=db2','SELECT id, code FROM table2')
AS tb2(id int, code text);
) AS tb2 ON tb2.column = tb1.column;
Примечание: я даю эту информацию для использования в будущем. Ссылка
Если кому-то нужен более сложный пример выполнения запросов между базами данных, вот пример, который очищает таблицу databasechangeloglock во всех базах данных, в которых она есть:
CREATE EXTENSION IF NOT EXISTS dblink;
DO
$$
DECLARE database_name TEXT;
DECLARE conn_template TEXT;
DECLARE conn_string TEXT;
DECLARE table_exists Boolean;
BEGIN
conn_template = 'user=myuser password=mypass dbname=';
FOR database_name IN
SELECT datname FROM pg_database
WHERE datistemplate = false
LOOP
conn_string = conn_template || database_name;
table_exists = (select table_exists_ from dblink(conn_string, '(select Count(*) > 0 from information_schema.tables where table_name = ''databasechangeloglock'')') as (table_exists_ Boolean));
IF table_exists THEN
perform dblink_exec(conn_string, 'delete from databasechangeloglock');
END IF;
END LOOP;
END
$$
Я проверил и попытался создать отношения внешнего ключа между двумя таблицами в двух разных базах данных, используя как dblink, так и postgres_fdw, но безрезультатно.
Прочитав отзывы других людей по этому поводу, например здесь и здесь и в некоторых других источниках, похоже, что в настоящее время нет способа сделать это:
dblink и postgres_fdw действительно позволяют подключаться и запрашивать таблицы в других базах данных, что невозможно со стандартным Postgres, но они не позволяют устанавливать отношения внешнего ключа между таблицами в разных базах данных.
см. https://www.cybertec-postgresql.com/en/joining-data-from-multiple-postgres-databases/ [опубликовано в 2017 г.]
В наши дни у вас также есть возможность использовать https://prestodb.io/
Вы можете запустить SQL на этом узле PrestoDB, и он будет распространять SQL-запрос по мере необходимости. Он может подключаться к одному и тому же узлу дважды для разных баз данных или может подключаться к разным узлам на разных хостах.
Не поддерживает:
DELETE
ALTER TABLE
CREATE TABLE (CREATE TABLE AS is supported)
GRANT
REVOKE
SHOW GRANTS
SHOW ROLES
SHOW ROLE GRANTS
Поэтому вы должны использовать его только для нужд SELECT и JOIN. Подключитесь напрямую к каждой базе данных для вышеуказанных потребностей. (Похоже, вы также можете ВСТАВИТЬ или ОБНОВИТЬ, что приятно)
Клиентские приложения подключаются к PrestoDB в основном с помощью JDBC, но возможны и другие типы подключения, включая Веб-API, совместимый с Tableu.
Это инструмент с открытым исходным кодом, управляемый Linux Foundation и Presto Foundation.
The founding members of the Presto Foundation are: Facebook, Uber, Twitter, and Alibaba.
The current members are: Facebook, Uber, Twitter, Alibaba, Alluxio, Ahana, Upsolver, and Intel.
Если вы работаете в среде MySQL, то, что MySQL называет базами данных, на самом деле являются схемами (CREATE SCHEMA == CREATE DATABASE в MySQL), поэтому, если вы переносите что-то из MySQL с использованием нескольких баз данных, используйте схемы.