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


143

我将基于以下错误消息(以及此Google结果)猜测答案为“否” ,但是是否仍然可以使用PostgreSQL执行跨数据库查询?

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

我正在处理一些分布在两个数据库中的数据,尽管数据实际上是在两个数据库之间共享的(一个数据库中的userid列来自另一个数据库中的users表)。我不知道为什么这些是两个独立的数据库而不是模式,但是请放心...

Answers:


111

注意:就像原始的问询者所暗示的那样,如果要在同一台计算机上设置两个数据库,则可能要创建两个模式 -在这种情况下,不需要任何特殊的查询即可在它们之间进行查询。

postgres_fdw

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

请注意,还有其他流行数据源的外部数据包装器。目前,只有postgres_fdwfile_fdw属于Postgres官方发行版。

对于9.3之前的Postgres版本

不再支持该旧版本,但是如果您需要在2013年以前的Postgres安装中执行此操作,则有一个名为的函数dblink

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


需要安装postgresql-contrib之前dblink?还是postgresql-contrib包括dblink?然后,OP的查询将起作用,还是您必须以不同的方式查询它?
mpen 2011年

3
据我所知,dblink无法处理您想要跨越两个数据库的查询的情况。
Paul Tomblin 2012年

26

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

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

当给出两个文本参数时,首先将第一个作为持久连接的名称查找;如果找到,则在该连接上执行命令。如果未找到,则第一个参数与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;

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


21

在得出与您有关跨数据库查询的相同结论之前,我曾遇到过这一问题。我最后要做的是使用模式划分表空间,这样我可以将表分组,但仍然可以查询所有表。


17
如果您来自MySQL环境,则MySQL所谓的数据库实际上就是架构(CREATE SCHEMA == CREATE DATABASE),因此,如果您使用多个数据库从MySQL移植某些内容,请使用架构
MkV 2010年

10

仅添加更多信息。

除了当前数据库外,没有其他方法可以查询数据库。由于PostgreSQL加载特定于数据库的系统目录,因此无法确定跨数据库查询的行为。

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

PostgreSQL常见问题


5
此附加信息可能会产生误导,并可能阻止用户使用上述解决方案。
johan855

5

是的,您可以通过使用DBlink(仅适用于postgresql)和DBI-Link(允许使用外部跨数据库查询器)和TDS_LInk来允许对MS SQL Server运行查询。

我曾经使用DB-Link和TDS-link取得了巨大的成功。


2

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

这可以通过简单的插入触发器来完成,该触发器又调用dblink来更新另一个副本。也有成熟的复制选项(例如Slony),但这是不合时宜的。


2

如果有人需要有关如何进行跨数据库查询的更复杂的示例,那么以下示例将清理包含该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
$$

1

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

阅读了其他人对此的反馈,例如在这里这里以及在其他一些来源中,看来目前尚无办法:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.