一个 **外部表
** 是一个数据库对象,它代表存在于外部数据源(可能是另一个 PostgreSQL 节点或完全不同的系统)上的表,该表由 外部数据包装器
(FDW) 访问。
外部表
的查询方式与普通表完全相同,并且根据 FDW 实现,可以使用 INSERT
、UPDATE
和 DELETE
命令进行修改。但是,与本地 PostgreSQL 表相比,外部表提供的灵活性与性能之间存在权衡。
外部表
自 PostgreSQL 9.1 起可用。
创建外部表
在创建 外部表
之前,必须安装相应的 外部数据包装器
,并创建一个 外部服务器
来定义与远程数据源的连接。通常还需要 用户映射
,允许本地 PostgreSQL 用户访问远程数据源。
定义 外部表
时,可以提供表和列级别的选项,这些选项通常可以将 PostgreSQL 中的表/列名称映射到远程数据源中的名称,并且根据 FDW 实现,还可以指定其他设置,例如远程表是否可以更新。
也可以使用 IMPORT FOREIGN SCHEMA
命令从远程数据源自动导入外部表,但这取决于远程数据源是否适合此类操作(例如,对于基于文件的 file_fdw
从文件中提取模式是不可行的)以及各个 FDW
提供的实现。
外部表作为分区
从 PostgreSQL 11 开始,外部表
可以作为分区表附加,尽管存在某些限制。
- 外部数据包装器 必须支持
元组路由
- 无法验证
外部表
中的所有行是否都符合分区约束 - 如果父表上存在任何唯一索引,则无法创建/附加
外部表
作为父表的 partition - 可以将行从本地分区移动到
外部表
分区,但不能将行从外部表分区移动到另一个分区
转储外部表数据
从 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 文档: 外部数据