PostgreSQL로 데이터베이스 간 쿼리를 수행 할 수 있습니까?


143

아래 오류 메시지 (및 이 Google 결과 )를 기반으로 대답이 "아니오"라고 생각 하지만 PostgreSQL을 사용하여 데이터베이스 간 쿼리를 수행해야합니까?

databaseA=# select * from databaseB.public.someTableName;
ERROR:  cross-database references are not implemented:
 "databaseB.public.someTableName"

데이터가 실제로 두 데이터베이스간에 공유되지만 두 데이터베이스간에 파티션 된 일부 데이터로 작업하고 있습니다 (한 데이터베이스의 사용자 열은 다른 데이터베이스의 users테이블에서 나옵니다 ). 왜 이것이 스키마 대신 두 개의 별도 데이터베이스인지 모르겠지만 c'est la vie ...

답변:


111

참고 : 원래 질문에서 알 수 있듯이 동일한 머신에 두 개의 데이터베이스를 설정 하는 경우 대신 두 개의 스키마 를 작성하려고 할 수 있습니다.이 경우 데이터베이스 를 쿼리하는 데 특별한 것이 필요하지 않습니다.

postgres_fdw

사용 postgres_fdw(해외 데이터 래퍼) 어떤 포스트 그레스 데이터베이스의 테이블에 연결 - 로컬 또는 원격.

이 참고 것을 다른 인기있는 데이터 소스에 대한 외부 데이터 래퍼 . 이 때, 단지 postgres_fdwfile_fdw공식 포스트 그레스 분포의 일부입니다.

9.3 이전의 Postgres 버전

이 이전 버전은 더 이상 지원되지 않지만 2013 년 이전 Postgres 설치에서이 작업을 수행해야하는 경우라는 기능이 dblink있습니다.

나는 그것을 사용한 적이 없지만 PostgreSQL의 나머지 부분과 함께 유지 관리되고 배포됩니다. Linux 배포판과 함께 제공된 PostgreSQL 버전을 사용하는 경우 postgresql-contrib라는 패키지를 설치해야 할 수 있습니다.


postgresql-contrib전에 설치 해야 dblink합니까? 또는 postgresql-contrib포함 dblink? 그런 다음 OP의 쿼리가 작동합니까, 아니면 다르게 쿼리해야합니까?
mpen

3
내가 읽을 수있는 것에서 dblink는 두 데이터베이스에 걸쳐있는 쿼리를 원하는 경우를 처리하지 않습니다.
Paul Tomblin

26

dblink () -원격 데이터베이스에서 쿼리를 실행합니다

dblink는 원격 데이터베이스에서 쿼리 (일반적으로 SELECT이지만 행을 반환하는 모든 SQL 문일 수 있음)를 실행합니다.

두 개의 텍스트 인수가 제공되면 첫 번째 인수는 먼저 영구 연결 이름으로 조회됩니다. 발견되면 해당 연결에서 명령이 실행됩니다. 찾을 수없는 경우 첫 번째 인수는 dblink_connect와 같이 연결 정보 문자열로 처리되며 표시된 연결은이 명령이 지속되는 동안 만 이루어집니다.

좋은 예 중 하나 :

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;

참고 : 나중에 참조 할 수 있도록이 정보를 제공하고 있습니다. 굴절


21

교차 데이터베이스 쿼리에 대해 동일한 결론을 내리기 전에이 문제를 해결했습니다. 내가 한 일은 테이블을 그룹화 할 수 있지만 테이블을 모두 쿼리 할 수있는 방식으로 테이블 스페이스를 나누기 위해 스키마를 사용하는 것이 었습니다.


17
MySQL 환경에서 온 경우, MySQL이라고 부르는 데이터베이스는 실제로 스키마 (MySQL의 CREATE SCHEMA == CREATE DATABASE)이므로 여러 데이터베이스를 사용하여 MySQL에서 무언가를 포팅하는 경우 스키마를 사용하십시오.
MkV

10

조금만 더 정보를 추가하십시오.

현재 데이터베이스 이외의 데이터베이스를 쿼리 할 수있는 방법이 없습니다. PostgreSQL은 데이터베이스 별 시스템 카탈로그를로드하기 때문에 데이터베이스 간 쿼리가 어떻게 작동해야하는지 확실하지 않습니다.

contrib / dblink는 함수 호출을 사용하여 데이터베이스 간 쿼리를 허용합니다. 물론 클라이언트는 다른 데이터베이스에 동시에 연결하여 결과를 클라이언트쪽에 병합 할 수도 있습니다.

PostgreSQL FAQ


5
이 추가 정보는 오해의 소지가 있으므로 사용자가 위의 솔루션을 사용하지 못하게 할 수 있습니다.
johan855

5

예, DBlink (postgresql 만 해당) 및 DBI-Link (외부 교차 데이터베이스 쿼리자를 허용) 및 TDS_LInk를 사용하면 MS SQL Server에 대해 쿼리를 실행할 수 있습니다.

나는 DB-Link와 TDS-link를 성공적으로 사용하기 전에 사용했습니다.


2

성능이 중요하고 대부분의 쿼리가 읽기 전용 인 경우 데이터를 다른 데이터베이스로 복제하는 것이 좋습니다. 이것은 불필요한 데이터 복제처럼 보이지만 인덱스가 필요한 경우 도움이 될 수 있습니다.

이 작업은 간단한 삽입 트리거로 수행 할 수 있으며이 트리거는 다른 사본을 업데이트하기 위해 dblink를 호출합니다. 완전 복제 옵션 (예 : Slony)도 있지만 주제에 맞지 않습니다.


2

누군가가 데이터베이스 간 쿼리를 수행하는 방법에 대한 더 많은 관련 예제가 필요한 경우 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
$$

1

dblinkpostgres_fdw를 사용하여 서로 다른 두 데이터베이스의 두 테이블 사이에 외래 키 관계를 확인하려고했지만 결과가 없습니다.

예를 들어 여기여기 그리고 다른 소스에서 다른 사람들의 의견을 읽은 후에 는 현재 할 수있는 방법이없는 것 같습니다.

DBLINKpostgres_fdw 실제로 표준 포스트 그레스 불가능 다른 데이터베이스에 및 쿼리 테이블을 연결하는 일을 가능하게하지만, 서로 다른 데이터베이스의 테이블 사이의 외래 키 관계를 구축하는 것을 허용하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.