根据以下错误消息(以及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 ...
答案 0 :(得分:94)
注意:正如原始提问者暗示的那样,如果您在同一台计算机上设置两个数据库,则可能需要制作两个schemas - 在这种情况下,您不需要任何特殊的查询穿过他们。
您现在可以使用新的postgres_fdw
(外部数据包装器)连接到任何Postgres数据库中的表 - 本地或远程。
请注意foreign data wrappers for other popular data sources。目前,只有postgres_fdw
和file_fdw
是Postgres官方发布内容的一部分。
此功能不是默认PostgreSQL安装的一部分,但您可以将其添加。它名为dblink
。
我从未使用它,但它与PostgreSQL的其余部分一起维护和分发。如果您使用的是Linux发行版附带的PostgreSQL版本,则可能需要安装名为postgresql-contrib的软件包。
答案 1 :(得分:20)
在遇到与您交叉数据库查询相同的结论之前,我遇到了这个问题。我最终做的是使用模式来划分表空间,这样我可以保持表分组,但仍然查询它们。
答案 2 :(得分:16)
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允许使用函数调用进行跨数据库查询。当然,客户端也可以同时连接到不同的数据库,并在客户端合并结果。
答案 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个表之间创建外键关系,但没有结果。
已经阅读了其他人对此的反馈,例如here和here,在其他一些来源中,看来目前尚无此方法:
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 和英特尔。