2

考虑一下N台机器每个都有一个postgres数据库的情况,它有一个具有相同模式和含义的表A.出于性能方面的考虑,我确实需要坚持这种架构,但是通过整合所有集体数据来刷新每个数据库是一种痛苦。最简单的方法来做所有的Postgres数据库表的所有联合?

我已经能够自动完成这个程度是一个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

嗯,看起来我需要在N台主机上运行pg_basebackup(N-1)次,对吧?我不确定对pg_dump + scp方法有什么好处。它会自动合并每个表与UNION DISTINCT,就像我在我的SQL脚本中做的那样?另外,我不想合并我的其他表,只是表A. – seewalker

+0

您使用的是什么postgresql版本? – harmic

回答

3

我会使用外国表。

对于每个远程主机创建一个外部表。然后创建一个包含union查询的物化视图。

当你想刷新一切,你需要做的就是refresh materialized view tablea_combined。不需要倾销或恢复。

当然,假设您将所有可以连接到所有其他服务器的服务器组合在一起。

如果你只是想要一个方便的方式来选择所有这些表,一个简单的视图可能就足够了 - 如果性能足够好,这取决于你做了什么。

如果您使用9.5或更高版本,您可以创建一个分区表,uses inheritance将外部表合并到“主”服务器上的一个表中。为了达到这个效果,这需要您有一个标识“源”服务器的列,因此可以用作分区键。

1

What @a_horse said:在foreign tables上使用MATERIALIZED VIEW

另外,使用更简单的查询:

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 tableASELECT * FROM tableA的SQL简写。

相关问题