可以用PostgreSQL执行跨数据库查询吗?

时间:2008-09-05 17:09:14

标签: sql postgresql

根据以下错误消息(以及this Google result),我猜测答案是“否”,但是无论如何使用PostgreSQL执行跨数据库查询?

databaseA=# select * from databaseB.public.someTableName;
ERROR:  cross-database references are not implemented:
 "databaseB.public.someTableName"

我正在处理一些跨两个数据库分区的数据,尽管两者之间真的共享数据(一个数据库中的userid列来自另一个数据库中的users表)。我不知道为什么这些是两个独立的数据库而不是模式,但是c'est la vie ...

9 个答案:

答案 0 :(得分:94)

注意:正如原始提问者暗示的那样,如果您在同一台计算机上设置两个数据库,则可能需要制作两个schemas - 在这种情况下,您不需要任何特殊的查询穿过他们。

自9.3起更新

您现在可以使用新的postgres_fdw(外部数据包装器)连接到任何Postgres数据库中的表 - 本地或远程。

请注意foreign data wrappers for other popular data sources。目前,只有postgres_fdwfile_fdw是Postgres官方发布内容的一部分。

9.3之前的原始答案

此功能不是默认PostgreSQL安装的一部分,但您可以将其添加。它名为dblink

我从未使用它,但它与PostgreSQL的其余部分一起维护和分发。如果您使用的是Linux发行版附带的PostgreSQL版本,则可能需要安装名为postgresql-contrib的软件包。

答案 1 :(得分:20)

在遇到与您交叉数据库查询相同的结论之前,我遇到了这个问题。我最终做的是使用模式来划分表空间,这样我可以保持表分组,但仍然查询它们。

答案 2 :(得分:16)

dblink() - 在远程数据库中执行查询

  

dblink执行查询(通常是SELECT,但它可以是任何SQL   在远程数据库中返回行的语句。

     

当给出两个文本参数时,第一个参数首先被查找为   持久连接的名称;如果找到,则执行该命令   那个联系。如果未找到,则将第一个参数视为a   连接信息字符串与dblink_connect和指示的一样   连接仅在此命令的持续时间内进行。

一个很好的例子:

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;

注意:我提供此信息以供将来参考。 Refrence

答案 3 :(得分:10)

只是添加更多信息。

  

无法查询当前数据库以外的数据库。因为PostgreSQL加载了特定于数据库的系统目录,所以不确定跨数据库查询应该如何表现。

     

contrib / dblink允许使用函数调用进行跨数据库查询。当然,客户端也可以同时连接到不同的数据库,并在客户端合并结果。

PostgreSQL FAQ

答案 4 :(得分:5)

是的,您可以使用DBlink(仅限postgresql)和DBI-Link(允许外部跨数据库查询器)和TDS_LInk,它允许对MS SQL服务器运行查询。

我之前使用过DB-Link和TDS-link取得了巨大的成功。

答案 5 :(得分:2)

如果性能很重要且大多数查询都是只读的,我建议将数据复制到另一个数据库。虽然这似乎是不必要的重复数据,但如果需要索引可能会有所帮助。

这可以通过简单的插入触发器来完成,而触发器又调用dblink来更新另一个副本。还有完整的复制选项(如Slony),但那是偏离主题的。

答案 6 :(得分:0)

如果有人需要更多有关如何进行跨数据库查询的示例,下面的示例将清理每个拥有该数据库的数据库上的databasechangeloglock表:

CREATE EXTENSION IF NOT EXISTS dblink;

DO 
$$
DECLARE database_name TEXT;
DECLARE conn_template TEXT;
DECLARE conn_string TEXT;
DECLARE table_exists Boolean;
BEGIN
    conn_template = 'user=myuser password=mypass dbname=';

    FOR database_name IN
        SELECT datname FROM pg_database
        WHERE datistemplate = false
    LOOP
        conn_string = conn_template || database_name;

        table_exists = (select table_exists_ from dblink(conn_string, '(select Count(*) > 0 from information_schema.tables where table_name = ''databasechangeloglock'')') as (table_exists_ Boolean));
        IF table_exists THEN
            perform dblink_exec(conn_string, 'delete from databasechangeloglock');
        END IF;     
    END LOOP;

END
$$

答案 7 :(得分:0)

我已经检查并尝试使用 dblink postgres_fdw 在2个不同数据库的2个表之间创建外键关系,但没有结果。

已经阅读了其他人对此的反馈,例如herehere,在其他一些来源中,看来目前尚无此方法:

dblink postgres_fdw 确实使人们能够连接和查询其他数据库中的表,这对于标准Postgres来说是不可能的,但是它们不允许建立不同数据库中的表之间的外键关系。

答案 8 :(得分:0)

参见 https://www.cybertec-postgresql.com/en/joining-data-from-multiple-postgres-databases/ [2017 年发布]

现在您还可以选择使用 https://prestodb.io/

您可以在该 PrestoDB 节点上运行 SQL,它将根据需要分发 SQL 查询。它可以为不同的数据库连接到同一个节点两次,也可能连接到不同主机上的不同节点。

不支持:

DELETE
ALTER TABLE
CREATE TABLE (CREATE TABLE AS is supported)
GRANT
REVOKE
SHOW GRANTS
SHOW ROLES
SHOW ROLE GRANTS

所以你应该只将它用于 SELECT 和 JOIN 需求。直接连接到每个数据库以满足上述需求。 (看起来你也可以插入或更新,这很好)

客户端应用程序主要使用 JDBC 连接到 PrestoDB,但其他类型的连接也是可能的,包括 Tableu compatible web API

这是一个由 Linux 基金会和 Presto 基金会管理的开源工具。

<块引用>

Presto 基金会的创始成员有:Facebook、Uber、 推特和阿里巴巴。

目前成员有:Facebook、Uber、Twitter、阿里巴巴、Alluxio、 Ahana、Upsolver 和英特尔。