PostgreSQL ile veritabanları arası sorgular gerçekleştirmek mümkün mü?


144

Aşağıdaki hata iletisine (ve bu Google sonucuna ) göre cevabın "hayır" olduğunu tahmin edeceğim , ancak yine de PostgreSQL kullanarak çapraz veritabanı sorgusu gerçekleştirmek için var mı?

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

Her ne kadar veri gerçekten (bir veritabanındaki userid sütunları usersdiğer veritabanındaki tablodan gelir) arasında paylaşılan rağmen iki veritabanları arasında bölümlenmiş bazı verilerle çalışıyorum . Bunların neden şema yerine iki ayrı veri tabanı olduğu hakkında hiçbir fikrim yok, ancak ...

Yanıtlar:


111

Not: Orijinal askerin ima ettiği gibi, aynı makinede iki veritabanı kuruyorsanız, bunun yerine muhtemelen iki şema yapmak istersiniz - bu durumda, bunları sorgulamak için özel bir şeye ihtiyacınız yoktur.

postgres_fdw

Kullanım postgres_fdw(yabancı veri sarıcı) bir Postgres veritabanı tablo bağlanmak için - yerel veya uzak.

Diğer popüler veri kaynakları için yabancı veri paketleyicileri olduğunu unutmayın . Şu anda, sadece postgres_fdwve file_fdwresmi Postgres dağıtımının bir parçasıdır.

9.3'ten önceki Postgres sürümleri için

Bu eski sürümler artık desteklenmemektedir, ancak bunu 2013 öncesi Postgres kurulumunda yapmanız gerekiyorsa, dblink .

Hiç kullanmadım, ancak PostgreSQL'in geri kalanı ile korunur ve dağıtılır. Linux dağıtımınızla birlikte verilen PostgreSQL sürümünü kullanıyorsanız, postgresql-antlw adlı bir paket yüklemeniz gerekebilir.


Daha postgresql-contribönce yüklemeniz dblinkmi gerekiyor ? Veya postgresql-contribiçerir dblink? Ve sonra OP'nin sorgusu işe yarayacak mı yoksa farklı bir şekilde sorgulamanız mı gerekiyor?
19.Haziran 1911

3
Ne okuyabilir itibaren, dblink iki veritabanlarını kapsayan bir sorgu istediğiniz durumda işlemez.
Paul Tomblin

27

dblink () - uzak veritabanında bir sorgu yürütür

dblink, uzak bir veritabanında bir sorgu yürütür (genellikle SELECT, ancak satırları döndüren herhangi bir SQL ifadesi olabilir).

İki metin argümanı verildiğinde, ilk metin ilk olarak kalıcı bağlantının adı olarak aranır; bulunursa, komut bu bağlantıda yürütülür. Bulunamazsa, ilk bağımsız değişken dblink_connect için olduğu gibi bir bağlantı bilgisi dizesi olarak kabul edilir ve belirtilen bağlantı yalnızca bu komutun süresi boyunca yapılır.

iyi örneklerden biri:

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;

Not: Bu bilgiyi ileride başvurmak üzere veriyorum. refrence


21

Sizinle çapraz veritabanı sorguları hakkında aynı sonuca gelmeden önce bu içine koştu. Ne kadar sona erdi ben tabloları gruplanmış tutmak ama yine de hepsini sorgulamak tablo şekilde bölmek için şemalar kullanmak oldu.


17
Bir MySQL ortamından geliyorsanız, MySQL'in veritabanlarını çağırdığı şemalar gerçekten şemalardır (MySQL'de CREATE SCHEMA == DATABASE OLUŞTUR), bu nedenle birden fazla veritabanı kullanarak MySQL'den bir şey taşıyorsanız, şemalar kullanın
MkV

10

Sadece biraz daha bilgi eklemek için.

Geçerli veritabanı dışında bir veritabanını sorgulamanın bir yolu yoktur. PostgreSQL veritabanına özgü sistem katalogları yüklediğinden, veritabanları arası bir sorgunun nasıl davranması gerektiği belirsizdir.

antre / dblink işlev çağrılarını kullanarak veritabanları arası sorgulara izin verir. Tabii ki, bir istemci aynı zamanda farklı veritabanlarına eşzamanlı bağlantılar kurabilir ve sonuçları istemci tarafında birleştirebilir.

PostgreSQL Hakkında SSS


5
Bu ek bilgiler yanıltıcı olabilir ve kullanıcıların yukarıdaki çözümü kullanmalarını engelleyebilir.
johan855

5

Evet, DBlink (yalnızca postgresql) ve DBI-Link (yabancı çapraz veritabanı sorgularına izin verir) ve sorguların MS SQL sunucusunda çalıştırılmasına izin veren TDS_LInk kullanarak yapabilirsiniz.

Daha önce büyük bir başarı ile DB-Link ve TDS-link kullandım.


2

Performans önemliyse ve çoğu sorgu salt okunursa, verileri başka bir veritabanına çoğaltmanızı öneririm. Bu, verilerin gereksiz bir şekilde çoğaltılması gibi görünse de, dizinlerin gerekli olup olmadığına yardımcı olabilir.

Bu, başka bir kopyayı güncellemek için dblink çağrısı yapan basit ekleme tetikleyicileri ile yapılabilir. Tam gelişmiş çoğaltma seçenekleri de var (Slony gibi) ama konu dışı.


2

Birisinin veritabanları arası sorguların nasıl yapılacağı konusunda daha kapsamlı bir örneğe ihtiyaç duyması durumunda, burada databasechangeloglockbulunan her veritabanındaki tabloyu temizleyen bir örnek verilmiştir :

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

Kontrol ve dblink ve postgres_fdw hem de sonuç ile 2 farklı veritabanlarında 2 tablo arasında yabancı anahtar ilişkiler oluşturmaya çalıştım .

Diğer halkların bununla ilgili geri bildirimlerini okuduktan sonra, örneğin burada ve burada ve diğer bazı kaynaklarda şu anda bunu yapmanın bir yolu yok gibi görünüyor:

Dblink ve postgres_fdw gerçekten standart Postgres ile mümkün değildir diğer veritabanları, içinde ulaşım sağlayan sorgu tabloları bağlamak için bir olanak, ancak farklı veritabanlarında tablolar arasında yabancı anahtar ilişkileri kurmak için izin vermez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.