Có thể thực hiện các truy vấn cơ sở dữ liệu chéo với PostgreSQL?


143

Tôi sẽ đoán rằng câu trả lời là "không" dựa trên thông báo lỗi dưới đây (và kết quả Google này ), nhưng dù sao cũng có thể thực hiện truy vấn cơ sở dữ liệu chéo bằng PostgreQuery?

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

Tôi đang làm việc với một số dữ liệu được phân vùng trên hai cơ sở dữ liệu mặc dù dữ liệu thực sự được chia sẻ giữa hai cơ sở (các cột userid trong một cơ sở dữ liệu đến từ usersbảng trong cơ sở dữ liệu khác). Tôi không biết tại sao đây là hai cơ sở dữ liệu riêng biệt thay vì lược đồ, nhưng đó là ...

Câu trả lời:


111

Lưu ý: Như người hỏi ban đầu ngụ ý, nếu bạn đang thiết lập hai cơ sở dữ liệu trên cùng một máy, bạn có thể muốn tạo hai lược đồ thay thế - trong trường hợp đó bạn không cần bất cứ điều gì đặc biệt để truy vấn chúng.

postgres_fdw

Sử dụng postgres_fdw(trình bao bọc dữ liệu nước ngoài) để kết nối với các bảng trong bất kỳ cơ sở dữ liệu Postgres nào - cục bộ hoặc từ xa.

Lưu ý rằng có các hàm bao dữ liệu nước ngoài cho các nguồn dữ liệu phổ biến khác . Tại thời điểm này, chỉ postgres_fdwfile_fdwlà một phần của phân phối Postgres chính thức.

Đối với các phiên bản Postgres trước 9.3

Các phiên bản cũ này không còn được hỗ trợ, nhưng nếu bạn cần thực hiện việc này trong bản cài đặt Postgres trước năm 2013, có một chức năng được gọi dblink.

Tôi chưa bao giờ sử dụng nó, nhưng nó được duy trì và phân phối với phần còn lại của PostgreSQL. Nếu bạn đang sử dụng phiên bản PostgreSQL đi kèm với bản phân phối Linux của mình, bạn có thể cần phải cài đặt gói có tên là postgresql-contrib.


Cần cài đặt postgresql-contribtrước dblink? Hay postgresql-contribbao gồm dblink? Và sau đó truy vấn của OP sẽ hoạt động hoặc bạn phải truy vấn nó theo cách khác?
mpen

3
Từ những gì tôi có thể đọc, dblink không xử lý trường hợp bạn muốn truy vấn mở rộng hai cơ sở dữ liệu.
Paul Tomblin

26

dblink () - thực hiện một truy vấn trong cơ sở dữ liệu từ xa

dblink thực thi một truy vấn (thường là CHỌN, nhưng nó có thể là bất kỳ câu lệnh SQL nào trả về các hàng) trong cơ sở dữ liệu từ xa.

Khi hai đối số văn bản được đưa ra, lần đầu tiên được tìm kiếm dưới dạng tên của một kết nối liên tục; nếu tìm thấy, lệnh được thực thi trên kết nối đó. Nếu không tìm thấy, đối số đầu tiên được coi là chuỗi thông tin kết nối như đối với dblink_connect và kết nối được chỉ định được thực hiện chỉ trong khoảng thời gian của lệnh này.

một trong những ví dụ điển hình:

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;

Lưu ý: Tôi đang cung cấp thông tin này để tham khảo trong tương lai. Chuyển hướng


21

Tôi đã gặp phải điều này trước khi đi đến kết luận tương tự về các truy vấn cơ sở dữ liệu chéo như bạn. Điều cuối cùng tôi làm là sử dụng các lược đồ để phân chia không gian bảng theo cách mà tôi có thể giữ các bảng được nhóm lại nhưng vẫn truy vấn tất cả.


17
Nếu bạn đến từ môi trường MySQL, thứ mà MySQL gọi là cơ sở dữ liệu thực sự là lược đồ (CREATE SCHema == CREATE DATABASE trong MySQL), vì vậy nếu bạn chuyển một cái gì đó từ MySQL bằng nhiều cơ sở dữ liệu, hãy sử dụng lược đồ
MkV

10

Chỉ cần thêm một chút thông tin.

Không có cách nào để truy vấn cơ sở dữ liệu ngoài cơ sở dữ liệu hiện tại. Vì PostgreQuery tải các danh mục hệ thống dành riêng cho cơ sở dữ liệu, nên không chắc chắn cách truy vấn cơ sở dữ liệu chéo sẽ hoạt động như thế nào.

contrib / dblink cho phép truy vấn cơ sở dữ liệu chéo bằng cách sử dụng các lệnh gọi hàm. Tất nhiên, một khách hàng cũng có thể thực hiện các kết nối đồng thời với các cơ sở dữ liệu khác nhau và hợp nhất các kết quả về phía khách hàng.

Câu hỏi thường gặp về PostgreSQL


5
Thông tin bổ sung này có thể gây hiểu nhầm và có thể không khuyến khích người dùng sử dụng giải pháp trên.
johan855

5

Có, bạn có thể bằng cách sử dụng DBlink (chỉ postgresql) và DBI-Link (cho phép các truy vấn cơ sở dữ liệu chéo nước ngoài) và TDS_LInk cho phép các truy vấn được chạy trên máy chủ MS SQL.

Tôi đã sử dụng DB-Link và TDS-link trước đây rất thành công.


2

Nếu hiệu suất là quan trọng và hầu hết các truy vấn là chỉ đọc, tôi sẽ đề nghị sao chép dữ liệu sang cơ sở dữ liệu khác. Mặc dù điều này có vẻ như trùng lặp dữ liệu không cần thiết, nhưng nó có thể hữu ích nếu các chỉ mục được yêu cầu.

Điều này có thể được thực hiện với đơn giản trên các kích hoạt chèn mà lần lượt gọi dblink để cập nhật một bản sao khác. Ngoài ra còn có các tùy chọn sao chép toàn diện (như Slony) nhưng không đúng chủ đề.


2

Trong trường hợp ai đó cần một ví dụ liên quan nhiều hơn về cách thực hiện các truy vấn cơ sở dữ liệu chéo, đây là một ví dụ giúp dọn sạch databasechangeloglockbảng trên mọi cơ sở dữ liệu có:

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

Tôi đã kiểm tra và cố gắng tạo mối quan hệ khóa ngoài giữa 2 bảng trong 2 cơ sở dữ liệu khác nhau bằng cả dblinkpostgres_fdw nhưng không có kết quả.

Đã đọc phản hồi của người khác về điều này, ví dụ ở đâyở đây và trong một số nguồn khác, có vẻ như không có cách nào để làm điều đó hiện tại:

Các dblinkpostgres_fdw thực sự cho phép một để kết nối và truy vấn bảng trong cơ sở dữ liệu khác, đó là không thể với các Postgres tiêu chuẩn, nhưng họ không cho phép thiết lập các mối quan hệ chính nước ngoài giữa các bảng trong cơ sở dữ liệu khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.