提问人:matt b 提问时间:9/6/2008 最后编辑:Kenny Linskymatt b 更新时间:5/21/2023 访问量:338279
可以使用PostgreSQL执行跨数据库查询吗?
Possible to perform cross-database queries with PostgreSQL?
问:
根据下面的错误消息(以及这个 Google 结果),我猜测答案是“否”,但是有没有使用 PostgreSQL 执行跨数据库查询?
databaseA=# select * from databaseB.public.someTableName;
ERROR: cross-database references are not implemented:
"databaseB.public.someTableName"
我正在处理一些跨两个数据库分区的数据,尽管数据实际上是在两个数据库之间共享的(一个数据库中的用户 id 列来自另一个数据库中的表)。我不知道为什么这是两个独立的数据库而不是模式,但是 c'est la vie...users
答:
在得出与您相同的跨数据库查询结论之前,我遇到过这个问题。我最终做的是使用模式来划分表空间,这样我就可以保持表分组,但仍然查询它们。
评论
注意:正如最初的提问者所暗示的那样,如果你在同一台机器上设置两个数据库,你可能希望创建两个模式——在这种情况下,你不需要任何特殊的东西来查询它们。
postgres_fdw
使用 postgres_fdw
(外部数据包装器)连接到任何 Postgres 数据库中的表(本地或远程)。
请注意,其他常用数据源也有外部数据包装器。目前,只有 和 是官方 Postgres 发行版的一部分。postgres_fdw
file_fdw
对于 9.3 之前的 Postgres 版本
不再支持这么旧的版本,但如果您需要在 2013 年之前的 Postgres 安装中执行此操作,可以使用一个名为 dblink
的函数。
我从未使用过它,但它与 PostgreSQL 的其余部分一起维护和分发。如果您使用的是 Linux 发行版附带的 PostgreSQL 版本,则可能需要安装名为 postgresql-contrib 的软件包。
评论
postgresql-contrib
dblink
postgresql-contrib
dblink
EXPLAIN ANALYZE
如果性能很重要,并且大多数查询都是只读的,我建议将数据复制到另一个数据库。虽然这似乎是不必要的数据重复,但如果需要索引,它可能会有所帮助。
这可以通过简单的插入触发器来完成,这些触发器又调用 dblink 来更新另一个副本。还有成熟的复制选项(如 Slony),但这是题外话。
是的,您可以使用 DBlink(仅限 postgresql)和 DBI-Link(允许外部跨数据库查询器)以及允许对 MS SQL 服务器运行查询的TDS_LInk。
我以前使用过 DB-Link 和 TDS-link,并取得了巨大的成功。
只是为了添加更多信息。
无法查询当前数据库以外的数据库。由于 PostgreSQL 加载特定于数据库的系统目录,因此不确定跨数据库查询的行为方式。
contrib/dblink 允许使用函数调用进行跨数据库查询。当然,客户端也可以同时连接到不同的数据库,并在客户端合并结果。
评论
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;
注意:我提供此信息以供将来参考。参考
评论
CREATE EXTENSION IF NOT EXISTS dblink;
如果有人需要有关如何执行跨数据库查询的更复杂的示例,下面是一个示例,用于清理每个具有它的数据库上的表: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
$$
我已经检查并尝试使用 dblink 和 postgres_fdw 在 2 个不同数据库中的 2 个表之间创建外键关系,但没有结果。
在阅读了其他人对此的反馈后,例如这里和这里以及其他一些来源,目前似乎没有办法做到这一点:
dblink 和 postgres_fdw确实允许人们连接和查询其他数据库中的表,这在标准 Postgres 中是不可能的,但它们不允许在不同数据库中的表之间建立外键关系。
请参阅 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 需求。直接连接到每个数据库以满足上述需求。(看起来你也可以INSERT或UPDATE,这很好)
客户端应用程序主要使用 JDBC 连接到 PrestoDB,但也可以进行其他类型的连接,包括与 Tableau 兼容的 Web API
这是一个由 Linux 基金会和 Presto 基金会管理的开源工具。
Presto基金会的创始成员有:Facebook、Uber、 Twitter和阿里巴巴。
目前成员有:Facebook、Uber、Twitter、阿里巴巴、Alluxio、 Ahana、Upsolver 和 Intel。
评论
在 Sybase/MSSQLServer 中,逻辑组织是db.user.table
在 Oracle 中,逻辑组织是schema.table
我知道在PostgreSQL中是,但不能共享db.schema.table
db
秘诀是在 Sybase 或 Oracle 中仅使用 2 级。db.<defaultuser.>table
schema.table
然后在 PostgreSQL 中,如果需要在级别之间共享表,请仅使用一个 db(不要创建多个数据库,仅使用 postgres),并使用多个模式,例如 Oracle:postgres.schemaX.table
评论