PostgreSQL 跨資料庫例項之間的資料訪問
前言
PostgresSQL 作為單示例多資料庫,通常一個數據庫例項會包含多個表空間和資料庫,一個表空間可以存放多個數據庫,在此關係中,一個表空間可以包含多個數據庫,但是一個數據庫只能屬於一個表空間,不能跨表空間存放。而表空間是一個邏輯概念,實質上在 PostgresSQL 中,一個表空間實際上就是一個可以供安裝 PostgresSQL 使用者讀寫的目錄,所以,一個數據庫集簇的最大大小取決於組成資料庫的這些表空間所對應目錄大小的總和大小。那麼這些多個數據庫組成的資料庫集簇可以用來隔離不同業務的資料,同時,也方便管理資料的儲存,但是,既然以資料庫來區分不同業務的資料,如果在一個數據庫集簇或者在屬於不同例項的資料庫集簇中,這些業務資料之間有可能有關聯資料,那麼此刻需要跨資料庫或者跨資料庫例項去訪問,如何才能實現?實現的方法有哪些?
上面問題的解決方式有以下幾種解決方案,分別是:
· 在同一個資料庫集簇或者跨例項的資料庫集簇中,可以通過 postgres_fdw 和 db_link 訪問。
· 使用 10 版本提供的LSR可以對需要的資料同步到查詢的資料庫例項上,從而在本地查詢。
postgres_fdw簡介
簡介
fdw(Foreign Data Wrapper),外部資料封裝器,使用 postgres_fdw 可以訪問外部 PostgreSQL 資料庫伺服器上的資料。postgres_fdw 專門為同構資料庫例項提供的外部封裝訪問擴充套件應用。fdw使用步驟如下:
· 建立擴充套件
· 建立服務
· 建立使用者對映
· 建立與訪問表對應的外表
1. 資料庫 db1 db2
使用 postgres 使用者建立兩個資料庫
[postgres@developer ~]$ psql -d postgres psql (13.4) Type "help" for help. postgres=# create database db1; CREATE DATABASE postgres=# create database db2; CREATE DATABASE
2. 表物件存放於不同的資料庫下
在兩個資料庫db1和db2中分別建立一張表
postgres=# \c db1 postgres You are now connected to database"db1" as user "postgres". db1=# create table tab_db1(id int,name varchar); CREATE TABLE db1=# \c db2 You are now connected to database "db2" as user "postgres". db2=# create table tab_db2(id int,name varchar); CREATE TABLE
3. 使用者訪問表不能跨庫訪問
如果使用以下方式訪問表,那麼db1 會被當作一個schema,所以不能使用該方式進行訪問
db2=# select * from db1.tab_db1; ERROR: relation "db1.tab_db1" does not exist LINE 1: select * from db1.tab_d
4. 使用 postgres_fdw
1)在 db1 上面建立擴充套件
[postgres@developer ~]$ psql -d db1 psql (13.4) Type "help" for help. db1=# create extension postgres_fdw ; CREATE EXTENSION
2)建立服務
db1=# CREATE SERVER IF NOT EXISTS foreigin_server_for_db2 FOREIGN DATA wrapper postgres_fdw OPTIONS (host 'localhost', port '5432', dbname 'db2'); CREATE SERVE
3) 建立使用者對映
db1=# CREATE USER MAPPING FOR postgres server foreigin_server_for_db2 options(user 'postgres',password 'postgres'); CREATE USER MAPPING
4) 建立本地外部表對映到遠端表
這裡的本地外部表的欄位需要和遠端待訪問的表的欄位一致
db1=# CREATE FOREIGN TABLE foreign_tab_db2 (id int,name varchar) SERVER foreigin_server_for_db2 OPTIONS(schema_name 'public',table_name 'tab_db2'); CREATE FOREIGN TABLE
5) 在 db2 的表中插入資料驗證
db1=# \c db2 postgres You are now connected to database "db2" as user "postgres". db2=# insert into tab_db2 values(1,'我是待訪問的表,我在 db2 中'); INSERT 0 1 db2=#
6) 在 db1 中去訪問
db2=# \c db1 postgres You are now connected to database "db1" as user "postgres". db1=# select * from foreign_tab_db2 ; id | name ----+---------------------------- 1 | 我是待訪問的表,我在 db2 中 (1 row)
總結
在使用 fdw 訪問外部封裝資料時,上面的例項展現的僅僅是同構資料庫之間的互相訪問,當然,fdw 也支援異構資料庫之間的互相訪問,如支援 mysql_fdw,redis_fdw,oracle_fdw,sqlserver_fdw,informix_fdw等