连接来自两个独立数据库的结果

Posted

技术标签:

【中文标题】连接来自两个独立数据库的结果【英文标题】:Joining Results from Two Separate Databases 【发布时间】:2011-06-08 09:50:04 【问题描述】:

是否可以 JOIN 来自两个单独的 postgres 数据库的行?

我正在使用在一台服务器中包含多个数据库的系统,有时我真的需要这样的功能。

【问题讨论】:

【参考方案1】:

根据http://wiki.postgresql.org/wiki/FAQ

除了当前数据库之外,没有其他方法可以查询数据库。 因为 PostgreSQL 加载特定于数据库的系统目录,所以它是 甚至不确定跨数据库查询的行为方式。 contrib/dblink 允许使用函数调用进行跨数据库查询。的 当然,客户端也可以同时连接到不同的 数据库并在客户端合并结果。

编辑:3 年后(2014 年 3 月),此常见问题解答条目已经过修订并且更有帮助:

如何使用多个数据库执行查询?

没有办法直接查询当前数据库以外的数据库 一。因为 PostgreSQL 加载特定于数据库的系统目录,所以它是 甚至不确定跨数据库查询的行为方式。

PostgreSQL 中的 SQL/MED 支持允许“外部数据包装器” 创建,将远程数据库中的表链接到本地​​数据库。 远程数据库可能是同一 PostgreSQL 上的另一个数据库 例如,或半个地球的数据库,都没有关系。 postgres_fdw 是 PostgreSQL 9.3 内置的,包括读/写 支持; 9.2 的只读版本可以编译和安装为 一个贡献模块。

contrib/dblink 允许使用函数调用和跨数据库查询 可用于更旧的 PostgreSQL 版本。不像 postgres_fdw 它不能将条件“下推”到远程服务器,所以它经常 获取比您需要的更多的数据。

当然,客户端也可以同时连接到 不同的数据库并在客户端合并结果。

【讨论】:

【参考方案2】:

忘记 dblink!

跟Postgres_FDW打个招呼:

准备使用postgres_fdw进行远程访问:

    使用CREATE EXTENSION 安装postgres_fdw 扩展。

    使用CREATE SERVER 创建一个外部服务器对象,以表示您要连接的每个远程数据库。指定连接 信息,除了用户和密码,作为服务器的选项 对象。

    使用CREATE USER MAPPING 为您希望允许访问每个外部服务器的每个数据库用户创建一个用户映射。指定 用作用户和密码选项的远程用户名和密码 用户映射。

    使用CREATE FOREIGN TABLEIMPORT FOREIGN SCHEMA 为您要访问的每个远程表创建一个外部表。列 外部表必须与引用的远程表匹配。你可以, 但是,使用与远程不同的表和/或列名 表的,如果您指定正确的远程名称作为选项 外部表对象。

现在您只需要外部表中的SELECT 即可访问数据 存储在其底层远程表中。

即使在大数据上也非常有用。

【讨论】:

这很好,直到我到达#4,你说我们需要创建外部表。基本上我们有 3 个独立的数据库,我需要像查询 1 个一样查询它们。尽管如果 3 个数据库中的任何一个发生任何更改,查询应该始终采用最新的架构和数据更改。 FDW 可以做到这一点吗? 您可以随时更新定义以反映目标表。它真的很快,值得付出任何努力。【参考方案3】:

是的,可以使用dblink 来执行此操作,尽管需要考虑重要的性能。

以下示例将要求当前 SQL 用户对两个数据库都具有权限。如果db2 不在同一个集群上,则需要将dbname=db2 替换为dblink documentation 中定义的完整连接字符串。

SELECT * 
FROM   table1 tb1 
LEFT   JOIN (
   SELECT *
   FROM   dblink('dbname=db2','SELECT id, code FROM table2')
   AS     tb2(id int, code text);
) AS tb2 ON tb2.column = tb1.column;

如果table2 非常大,您可能会遇到性能问题,因为子查询会在执行连接之前加载整个table2

【讨论】:

对我不起作用。我收到Query 1 ERROR: ERROR: syntax error at or near ";"【参考方案4】:

不,你不能。您可以使用 dblink 从一个数据库连接到另一个数据库,但如果您正在寻找 JOIN,这将无济于事。

您不能在单个数据库中使用不同的 SCHEMA 来存储所有数据吗?

【讨论】:

我不能,我们有一些充满数据的数据库,没有人想改变任何东西:/如果我要使用这个 dblink,我可以这样做:INSERT INTO DB1.table SELECT * FROM DB2.table; 如果你在db1中执行查询,你当然可以这样做,比如INSERT INTO db1_table(cols...) SELECT cols... FROM dblink('db2', 'SELECT cols... FROM db2_table') 我用这个dblink() 连接它,它总是对我有用 @araqnid cols... 是一个实际的语法快捷方式,还是你只是用它来表示他需要枚举语句中所有三个位置的列? 现在可以更新吗?我假设最好的选项是使用FDW,正如另一个答案所说...但只是假设...【参考方案5】:

只需几步,您就可以达到目标: follow this reference step by step

WE HAVE BEEN CONNECTED TO DB2 WITH TABLE TBL2 AND COLUMN COL2
ALSO THERE IS DB1 WITH TBL1 AND COLUMN COL1

 *** connecting to second db ie db2
    Now just **copy paste the 1-7 processes** (make sure u use correct username and password and ofcourse db name)

    1.**CREATE EXTENSION dblink;**

    2.**SELECT pg_namespace.nspname, pg_proc.proname 
    FROM pg_proc, pg_namespace 
    WHERE pg_proc.pronamespace=pg_namespace.oid 
       AND pg_proc.proname LIKE '%dblink%';**

    3.**SELECT dblink_connect('host=localhost user=postgres password=postgres dbname=db1');**

    4.**CREATE FOREIGN DATA WRAPPER postgres VALIDATOR postgresql_fdw_validator;**

    5.**CREATE SERVER postgres2 FOREIGN DATA WRAPPER postgres OPTIONS (hostaddr '127.0.0.1', dbname 'db1');**

    6.**CREATE USER MAPPING FOR postgres SERVER postgres2 OPTIONS (user 'postgres', password 'postgres');**

    7.**SELECT dblink_connect('postgres2');**

    ---Now, you can SELECT the data of Database_One from Database_Two and even join both db results:

    **SELECT * FROM public.dblink
    ('postgres2','SELECT col1,um_name FROM public.tbl1 ') 
    AS DATA(um_userid INTEGER),tbl2 where DATA.col1=tbl2.col2;**


You can also Check this :[How to join two tables of different databases together in postgresql [\[working finely in version 9.4\]][1]

【讨论】:

【参考方案6】:

你需要使用 dblink...就像上面提到的 araqnid,这样的东西可以正常工作:

选择 ST.Table_Name、ST.Column_Name、DV.Table_Name、DV.Column_Name、* 来自 information_schema.Columns ST 全外连接 dblink('dbname=otherdatabase','select Table_Name, Column_Name from information_schema.Columns') DV(Table_Name text, Column_Name 文本) 在 ST.Table_Name = DV.Table_name 和 ST.Column_Name = DV.Column_Name 其中 ST.Column_Name 为 null 或 DV.Column_Name 为 NULL

【讨论】:

【参考方案7】:

您使用了 postgresql 的 dblink 扩展。

Reference take from this Article:

PostgreSQL 的 DbLink 扩展,用于将一个数据库连接到另一个数据库。

安装 DbLink 扩展。

CREATE EXTENSION dblink;

验证 DbLink:

SELECT pg_namespace.nspname, pg_proc.proname 
FROM pg_proc, pg_namespace 
WHERE pg_proc.pronamespace=pg_namespace.oid 
   AND pg_proc.proname LIKE '%dblink%';

我已经为此准备了完整的演示。请访问我的帖子,逐步了解如何在 Postgresql 中执行跨数据库查询。

【讨论】:

好收获。并非所有人都知道您需要激活扩展程序。

以上是关于连接来自两个独立数据库的结果的主要内容,如果未能解决你的问题,请参考以下文章

检索表连接的结果

来自 2 个独立数据库的 Spring 回滚事务

使用来自两个数据库的自动增量 ID 连接来自两个表的数据

Spark 上的 Hive 不返回聚合或连接查询的结果

如何在java中合并来自两个不同数据库的两个不同结果集

连接来自不同数据库的两个表