【发布时间】:2011-06-08 09:50:04
【问题描述】:
是否可以 JOIN 来自两个单独的 postgres 数据库的行?
我正在使用在一台服务器中包含多个数据库的系统,有时我真的需要这样的功能。
【问题讨论】:
标签: postgresql join
是否可以 JOIN 来自两个单独的 postgres 数据库的行?
我正在使用在一台服务器中包含多个数据库的系统,有时我真的需要这样的功能。
【问题讨论】:
标签: postgresql join
根据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 它不能将条件“下推”到远程服务器,所以它经常 获取比您需要的更多的数据。
当然,客户端也可以同时连接到 不同的数据库并在客户端合并结果。
【讨论】:
忘记 dblink!
跟Postgres_FDW打个招呼:
准备使用
postgres_fdw进行远程访问:
使用
CREATE EXTENSION安装postgres_fdw扩展。使用
CREATE SERVER创建一个外部服务器对象,以表示您要连接的每个远程数据库。指定连接 信息,除了用户和密码,作为服务器的选项 对象。使用
CREATE USER MAPPING为您希望允许访问每个外部服务器的每个数据库用户创建一个用户映射。指定 用作用户和密码选项的远程用户名和密码 用户映射。使用
CREATE FOREIGN TABLE或IMPORT FOREIGN SCHEMA为您要访问的每个远程表创建一个外部表。列 外部表必须与引用的远程表匹配。你可以, 但是,使用与远程不同的表和/或列名 表的,如果您指定正确的远程名称作为选项 外部表对象。现在您只需要外部表中的
SELECT即可访问数据 存储在其底层远程表中。
即使在大数据上也非常有用。
【讨论】:
是的,可以使用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 ";"
不,你不能。您可以使用 dblink 从一个数据库连接到另一个数据库,但如果您正在寻找 JOIN,这将无济于事。
您不能在单个数据库中使用不同的 SCHEMA 来存储所有数据吗?
【讨论】:
INSERT INTO db1_table(cols...) SELECT cols... FROM dblink('db2', 'SELECT cols... FROM db2_table')
dblink() 连接它,它总是对我有用
cols... 是一个实际的语法快捷方式,还是你只是用它来表示他需要枚举语句中所有三个位置的列?
只需几步,您就可以达到目标: 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]
【讨论】:
你需要使用 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
【讨论】:
您使用了 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 中执行跨数据库查询。
【讨论】: