外部表 (foreign table) 是一个数据库对象,它表示一个存在于外部数据源(可以是另一个 PostgreSQL 节点或一个完全不同的系统)上的表,该表通过 外部数据包装器 (FDW) 进行访问。
外部表 可以像普通表一样被查询,并且取决于 FDW 的实现,还可以通过 INSERT、UPDATE 和 DELETE 命令进行修改。然而,外部表提供的灵活性与原生 PostgreSQL 表相比,在性能上会存在权衡。
外部表 自 PostgreSQL 9.1 起可用。
创建外部表
在创建 外部表 之前,必须安装相应的 外部数据包装器,并创建一个定义到远程数据源连接的 外部服务器。通常还需要 用户映射,它允许本地 PostgreSQL 用户访问远程数据源。
在定义 外部表 时,可以提供表和列级别的选项,这些选项通常能够将 PostgreSQL 中的表/列名映射到远程数据源上的名称,并且根据 FDW 的实现,还可以指定其他设置,例如远程表是否可更新。
外部表也可以使用 IMPORT FOREIGN SCHEMA 命令从远程数据源自动导入,尽管这是否可用取决于远程数据源是否适合此类操作(例如,对于基于文件的 file_fdw,从文件中提取模式是不可行的),以及相应 FDW 提供的实现。
外部表作为分区
从 PostgreSQL 11 开始,外部表 可以作为分区表附加,尽管存在某些限制/约束。
- 外部数据包装器必须支持
元组路由 - 不验证外部表中的所有行是否都遵守分区约束
- 如果父表上有任何唯一索引,则无法创建/附加
外部表作为父表的分区 - 行可以从本地分区移动到
外部表分区,但不能从外部表分区移动到另一个分区
转储外部表数据
从 PostgreSQL 13 开始,pg_dump 可以选择使用 --include-foreign-data 选项转储外部表的数据。
局限性
- 在 PostgreSQL 13 及更早版本中,无法使用
TRUNCATE命令从外部表中删除数据。 - 在 PostgreSQL 15 及更早版本中,无法在外部表上创建
TRUNCATE触发器 - 无法使用外部表作为
MERGE操作的目标关系
示例
使用 postgres_fdw 创建一个简单的“回环”外部表,该表实际上引用同一服务器上的表
postgres=# CREATE EXTENSION postgres_fdw; CREATE EXTENSION postgres=# CREATE SERVER fdw_test FOREIGN DATA WRAPPER postgres_fdw OPTIONS ( host 'localhost', port '5432', dbname 'postgres' ); postgres=# CREATE USER MAPPING FOR CURRENT_USER SERVER fdw_test OPTIONS(user 'postgres'); CREATE USER MAPPING postgres=# CREATE FOREIGN TABLE bar ( f_id INT OPTIONS (column_name 'id') NOT NULL, f_val TEXT OPTIONS (column_name 'val') ) SERVER fdw_test OPTIONS (table_name 'foo'); CREATE FOREIGN TABLE postgres=# \det List of foreign tables Schema | Table | Server --------+-------------+---------- public | bar | fdw_test (1 row) postgres=# \d bar Foreign table "public.bar" Column | Type | Collation | Nullable | Default | FDW options --------+---------+-----------+----------+---------+--------------------- f_id | integer | | not null | | (column_name 'id') f_val | text | | | | (column_name 'val') Server: fdw_test FDW options: (table_name 'foo')
参考资料
- PostgreSQL 文档: 外部数据
反馈
在此处 提交任何关于“外部表”的评论、建议或更正。