mysql和mssql的跨库查询,基本只需要dbname.schema.table_name就可以实现,而pg的跨库查询,和oracle一样,需要通过类似dblink的方式来实现。pg在9.3之前建议使用dblink,在9.3之后,建议使用postgres_fdw(foreign-data wrapper)。
我们假设有个库mydb001,里面有2个用户mydb001_rw和mydb001_r,分别是读写用户和只读用户。有另外一个库dbprd2,里面也是有2个用户dbprd2_rw和dbprd2_r。我们在mydb001库中利用mydb001_rw用户,查询dbprd2库的tb_orad_mutex表。
一、superuser安装extension
如果你需要每个database都使用,那么每个database都要装一次这个extension,或者也可以一开始就在template1中安装,那么后续新建的database也都会包含了这个extension:
psql -U dbmgr -d mydb001
--drop extension postgres_fdw;
create extension postgres_fdw;
mydb001=> \dx
List of installed extensions
Name | Version | Schema | Description
--------------+---------+------------+---------------------------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
postgres_fdw | 1.0 | public | foreign-data wrapper for remote PostgreSQL servers
uuid-ossp | 1.1 | public | generate universally unique identifiers (UUIDs)
(3 rows)
二、superuser创建remote server
--drop server remote_db;
create server remote_db foreign data wrapper postgres_fdw options(host '127.0.0.1',port '5432',dbname 'dbprd2');
mydb001=> \des
List of foreign servers
Name | Owner | Foreign-data wrapper
-----------+-------+----------------------
remote_db | dbmgr | postgres_fdw
(1 row)
GRANT USAGE ON FOREIGN SERVER remote_db TO mydb001_rw;
GRANT USAGE ON FOREIGN SERVER remote_db TO mydb001_r;
\q
注意此时修改pg_hba.conf文件,允许连接。
# TYPE DATABASE USER ADDRESS METHOD
……
host all all 127.0.0.1/32 md5
三、应用用户创建user mapping
psql -U mydb001_rw -d mydb001
--drop user mapping for mydb001_rw server remote_db;
create user mapping for mydb001_rw server remote_db options(user 'dbprd2_r',password 'xxx');
四、应用用户创建 FOREIGN TABLE
--drop FOREIGN TABLE db_dbprd2_tb_orad_mutex;
CREATE FOREIGN TABLE
db_dbprd2_tb_orad_mutex(appid integer,appkey character varying(40),appindex character varying(40) ,status integer)
server remote_db
options (schema_name 'dbprd2_rw',table_name 'tb_orad_mutex');
五、测试查询及能否更新
如果mapping user时用的是读写用户,那么也是可以更新的
-- mydb001_rw用户查询dbprd2数据库的表。
psql -U mydb001_rw -d mydb001
mydb001=> select * from db_dbprd2_tb_orad_mutex limit 2;
appid | appkey | appindex | status
--------+------------------+----------------+--------
123456 | AAAAAAAAAAAAAAAA | lm | 999
654321 | BBBBBBBBBBBBBBB | abcdefghijklm | 999
(2 rows)
--由于之前的user mapping是通过只读用户连接,所以更新操作会报错:
mydb001=> begin;
BEGIN
mydb001=> update db_dbprd2_tb_orad_mutex set appindex='zxsaqwerre' where appid='654321' and appkey='BBBBBBBBBBBBBBB';
ERROR: permission denied for relation tb_orad_mutex
CONTEXT: Remote SQL command: UPDATE dbprd2_rw.tb_orad_mutex SET appindex = 'zxsaqwerre'::character varying(40) WHERE ((appid = 654321)) AND ((appkey = 'BBBBBBBBBBBBBBB'::text))
mydb001=> rollback;
ROLLBACK