前言
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等