Postgres数据库表的全部联盟的最简单方法?

时间:2016-11-10 19:01:52

标签: postgresql database-design duplicates union distributed-caching

考虑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中描述了一些分布式数据库方法,但是它们中的任何一个都可以做到这一点,否则不会强迫我重新思考或重新设计我的数据库吗?

2 个答案:

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