1、本次使用 postgres_fdw 为例
2、PG版本 9.4.5,编译过程就不说了,安装到了两个目录,其中一个运行于6432端口,用作外部服务器,另一个运行于默认5432,后边以它们的端口号称呼便于区别。
3、在5432上创建外部服务器与用户影射:
CREATE SERVER foreign_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '127.0.0.1', port '6432', dbname 'postgres'); -- 创建用户影射 CREATE USER MAPPING FOR quanzl SERVER foreign_server OPTIONS (user 'quanzl', password '');
4、创建外部表:
CREATE FOREIGN TABLE foreign_table ( id serial NOT NULL, data text ) SERVER foreign_server OPTIONS (schema_name 'public', table_name 'some_table');
运行后会提示:
ERROR: relation "public.some_table" does not exist CONTEXT: Remote SQL command: SELECT id, data FROM public.some_table STATEMENT: select * from foreign_table; ERROR: relation "public.some_table" does not exist CONTEXT: Remote SQL command: SELECT id, data FROM public.some_table
5、我们去6432看,并没有表建成,说明 fdw 根本不管对方表创建,干掉5432上的表重来
DROP FOREIGN TABLE foreign_table;
6、在6432上建表:
CREATE TABLE some_table(id serial NOT NULL,data text);
7、再次用第5步的语句建表后查询:
postgres=# select * from foreign_table; id | data ----+------ (0 rows) postgres=#
8、我们尝试在两个结点插入数据,会发现:
select * from some_table; id | data ----+------------- 1 | remote data 1 | local data (2 rows) postgres=#
说明序列号是在两个结点上分别起作用的,外部表使用 serial 可能会带来问题
9、重新创建,第一个字段指定为 int,结果发现:
postgres=# insert into foreign_table(data) values('remote data 2'); ERROR: null value in column "id" violates not-null constraint DETAIL: Failing row contains (null, remote data 2). CONTEXT: Remote SQL command: INSERT INTO public.some_table(id, data) VALUES ($1, $2) STATEMENT: insert into foreign_table(data) values('remote data 2'); ERROR: null value in column "id" violates not-null constraint DETAIL: Failing row contains (null, remote data 2). CONTEXT: Remote SQL command: INSERT INTO public.some_table(id, data) VALUES ($1, $2) postgres=#
10、创建一个不包含 id 的外部表,并插入数据:
CREATE FOREIGN TABLE foreign_table ( data text ) SERVER foreign_server OPTIONS (schema_name 'public', table_name 'some_table'); INSERT INTO foreign_table(data) VALUES('remote data 2'); SELECT * FROM foreign_table;
至少可以正常使用了,只是涉及序列号处理的时候,表结构设计还需要好好思量一下。