执行 Postgres 数据库表的所有联合的最简单方法?

Easiest Way To Do All-To-All Union Of Postgres Database Tables?

考虑这样一种情况,N 台机器各有一个 postgres 数据库,具有相同架构和含义的 table 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 中描述了一些分布式数据库方法,但它们中的任何一个都可以做到这一点,否则不会迫使我重新考虑或重新设计我的数据库吗?

我会为此使用外国 tables。

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

当你想刷新一切时,只需要refresh materialized view tablea_combined。无需转储或恢复。

当然,这是假设您所在的服务器可以连接到所有其他服务器。

如果您只是想要一种方便的方式来 select 所有这些 table,一个简单的视图可能就足够了 - 如果性能足够好,这取决于您使用它做什么。

如果您使用 9.5 或更高版本,您可以创建一个分区 table,uses inheritance 将您的 "master" 上的外部 table 合并为一个 table服务器。为了提高效率,这需要您有一个标识 "source" 服务器的列,因此可以用作分区键。

: Use a MATERIALIZED VIEW on 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 returns 不同的行,不需要多余的 DISTINCT。 (您将使用 UNION ALL 保留重复项。)

  • TABLE tableA 是 SQL shorthand for SELECT * FROM tableA.