考虑N机器每个都有一个postgres数据库,具有相同模式和含义的表A的情况。出于性能原因,我确实需要坚持这种架构,但是使用所有集合数据的联合刷新每个数据库都是一种痛苦。
我能够实现自动化的程度是一个shell脚本:
mycopy=tableA_`hostname`.pg
pg_dump -t tableA -d $database | sed "s/tableA/$mycopy" > $mycopy
for host in host_x host_y host_z; do
scp $mycopy host:~/
done
然后是sql脚本:
BEGIN;
\i tableA_hostx.pg
\i tableA_hosty.pg
\i tableA_hostz.pg
CREATE TABLE new_tableA AS
(select * from tableA)
UNION DISTINCT (select * from tableA_hostx)
UNION DISTINCT (select * from tableA_hosty)
UNION DISTINCT (select * from tableA_hostz);
DROP TABLE tableA;
DROP TABLE table_hostx;
DROP TABLE table_hosty;
DROP TABLE table_hostz;
ALTER TABLE new_tableA rename to tableA;
COMMIT;
但这是一个我觉得我正在做的非常明确和普通的事情,所以我想知道是否有一些先进的高级接口用于这种全面的通信。 the postgres wiki中描述了一些分布式数据库方法,但是它们中的任何一个都可以做到这一点,否则不会强迫我重新思考或重新设计我的数据库吗?
答案 0 :(得分:3)
我会使用外国表格。
为每个远程主机创建一个外部表。然后创建包含union
查询的物化视图。
当您想要刷新所有内容时,您需要做的就是refresh materialized view tablea_combined
。不需要倾倒或恢复。
当然,假设您将所有可以连接到所有其他服务器的服务器组合在一起。
如果您只是想要一种方便的方法来选择所有这些表,那么简单的视图可能就足够了 - 如果性能足够好,它取决于您使用它做什么。
如果使用9.5或更高版本,则可以创建一个分区表,uses inheritance将外部表组合到“主”服务器上的一个表中。为了提高效率,这需要您有一个标识“源”服务器的列,因此可以用作分区键。
答案 1 :(得分:1)
What @a_horse said:在MATERIALIZED VIEW
上使用foreign tables。
另外,使用更简单的查询:
CREATE MATERIALIZED VIEW new_tableA AS
TABLE tableA
UNION TABLE tableA_hostx -- being a foreign table
UNION TABLE tableA_hosty
UNION TABLE tableA_hostz;
UNION
无论如何都会返回不同的行,不需要冗余的DISTINCT
。 (您将使用UNION ALL
保留重复项。)
TABLE tableA
是SELECT * FROM tableA
的SQL简写。