2024 年 9 月 26 日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1

创建外部表

CREATE FOREIGN TABLE — 定义新的外部表

概要

CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
  SERVER server_name
[ OPTIONS ( option 'value' [, ... ] ) ]

CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name
  PARTITION OF parent_table [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ]
{ FOR VALUES partition_bound_spec | DEFAULT }
  SERVER server_name
[ OPTIONS ( option 'value' [, ... ] ) ]

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL |
  NULL |
  CHECK ( expression ) [ NO INHERIT ] |
  DEFAULT default_expr |
  GENERATED ALWAYS AS ( generation_expr ) STORED }

and table_constraint is:

[ CONSTRAINT constraint_name ]
CHECK ( expression ) [ NO INHERIT ]

and partition_bound_spec is:

IN ( partition_bound_expr [, ...] ) |
FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] )
  TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS numeric_literal, REMAINDER numeric_literal )

描述

CREATE FOREIGN TABLE 在当前数据库中创建一个新的外部表。该表将由发出命令的用户拥有。

如果指定了模式名称(例如,CREATE FOREIGN TABLE myschema.mytable ...),则该表将在指定的模式中创建。否则,它将在当前模式中创建。外部表的名称必须与同一模式中的任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。

CREATE FOREIGN TABLE 还会自动创建一个数据类型,该数据类型代表与外部表的一行相对应的复合类型。因此,外部表不能与同一模式中的任何现有数据类型具有相同的名称。

如果指定了 PARTITION OF 子句,则该表将作为 parent_table 的分区创建,并具有指定的边界。

要创建外部表,您必须对外部服务器具有 USAGE 权限,以及对表中使用的所有列类型具有 USAGE 权限。

参数

IF NOT EXISTS

如果具有相同名称的关系已存在,则不要抛出错误。在这种情况下会发出通知。请注意,无法保证现有关系与将要创建的关系有任何相似之处。

table_name

要创建的表的名称(可以选择模式限定)。

column_name

要在新表中创建的列的名称。

data_type

列的数据类型。这可以包括数组说明符。有关 PostgreSQL 支持的数据类型的更多信息,请参阅第 8 章

COLLATE collation

COLLATE 子句将排序规则分配给列(必须是可排序的数据类型)。如果未指定,则使用列数据类型的默认排序规则。

INHERITS ( parent_table [, ... ] )

可选的 INHERITS 子句指定了新外部表自动继承所有列的表的列表。父表可以是普通表或外部表。有关更多详细信息,请参阅 CREATE TABLE 的类似形式。

PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT }

此形式可用于创建外部表作为给定父表的划分,并具有指定的划分边界值。有关更多详细信息,请参阅 CREATE TABLE 的类似形式。请注意,如果父表上存在 UNIQUE 索引,则目前不允许创建外部表作为父表的划分。(另请参见ALTER TABLE ATTACH PARTITION。)

CONSTRAINT constraint_name

列或表约束的可选名称。如果违反了约束,则约束名称会出现在错误消息中,因此可以使用诸如 col must be positive 之类的约束名称来向客户端应用程序传达有用的约束信息。(需要双引号来指定包含空格的约束名称。)如果未指定约束名称,则系统会生成一个名称。

NOT NULL

不允许列包含空值。

NULL

允许列包含空值。这是默认设置。

此子句仅为了与非标准 SQL 数据库兼容而提供。建议在新的应用程序中不使用它。

CHECK ( expression ) [ NO INHERIT ]

CHECK 子句指定了一个表达式,该表达式生成一个布尔结果,外部表中的每一行都应满足该结果;也就是说,对于外部表中的所有行,该表达式应生成 TRUE 或 UNKNOWN,而不是 FALSE。

当前,CHECK 表达式不能包含子查询,也不能引用当前行以外的变量。可以引用系统列 tableoid,但不能引用任何其他系统列。

标记为 NO INHERIT 的约束不会传播到子表。

DEFAULT default_expr

DEFAULT 子句为其列定义中包含该子句的列分配默认数据值。该值是任何无变量表达式(子查询和对当前表中其他列的交叉引用不允许)。默认表达式的數據類型必須與列的數據類型匹配。

默认表达式将用于任何不为列指定值的插入操作。如果列没有默认值,则默认值为 null。

GENERATED ALWAYS AS ( generation_expr ) STORED

此子句将列创建为生成列。不能写入该列,读取时将返回指定表达式的结果。

关键字 STORED 是必需的,表示该列将在写入时计算。(计算后的值将提供给外部数据包装器进行存储,并且必须在读取时返回。)

生成表达式可以引用表中的其他列,但不能引用其他生成列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。

server_name

要用于外部表的现有外部服务器的名称。有关定义服务器的详细信息,请参阅创建服务器

OPTIONS ( option 'value' [, ...] )

与新外部表或其列之一关联的选项。允许的选项名称和值特定于每个外部数据包装器,并且使用外部数据包装器的验证器函数进行验证。不允许重复选项名称(尽管表选项和列选项可以使用相同的名称是可以的)。

备注

外部表上的约束(例如 CHECKNOT NULL 子句)不会由核心 PostgreSQL 系统强制执行,并且大多数外部数据包装器也不会尝试强制执行它们;也就是说,假设约束始终为真。这种强制执行几乎没有意义,因为它只适用于通过外部表插入或更新的行,而不适用于通过其他方式(例如直接在远程服务器上)修改的行。相反,附加到外部表的约束应代表由远程服务器强制执行的约束。

一些专用外部数据包装器可能是访问其访问数据的唯一访问机制,在这种情况下,外部数据包装器本身可能适合执行约束强制执行。但是,您不应该假设包装器执行此操作,除非其文档中说明了这一点。

虽然 PostgreSQL 不会尝试强制执行外部表上的约束,但它假设它们在查询优化方面是正确的。如果在外部表中可见的行不满足声明的约束,则对该表的查询可能会产生错误或不正确的结果。确保约束定义与实际情况相符是用户的责任。

注意

当外部表用作分区表的划分时,存在一个隐式约束,即其内容必须满足划分规则。同样,确保这种情况属实是用户的责任,这最好通过在远程服务器上安装匹配的约束来完成。

在包含外部表划分的划分表中,如果外部数据包装器支持元组路由,则更改划分键值的 UPDATE 会导致一行从本地划分移动到外部表划分。但是,目前无法将行从外部表划分移动到另一个划分。假设远程服务器适当地强制执行了划分约束,则需要执行此操作的 UPDATE 将因划分约束而失败。

类似的考虑因素适用于生成列。存储的生成列在本地 PostgreSQL 服务器上插入或更新时计算,并传递给外部数据包装器以写入到外部数据存储区,但没有强制执行对外部表的查询返回与生成表达式一致的存储的生成列的值。同样,这可能会导致查询结果不正确。

示例

创建外部表 films,它将通过服务器 film_server 访问

CREATE FOREIGN TABLE films (
    code        char(5) NOT NULL,
    title       varchar(40) NOT NULL,
    did         integer NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute
)
SERVER film_server;

创建外部表 measurement_y2016m07,它将通过服务器 server_07 访问,作为范围划分表 measurement 的划分

CREATE FOREIGN TABLE measurement_y2016m07
    PARTITION OF measurement FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')
    SERVER server_07;

兼容性

CREATE FOREIGN TABLE 命令在很大程度上符合SQL标准;但是,与 CREATE TABLE 非常类似,允许使用 NULL 约束和零列外部表。指定列默认值的能力也是 PostgreSQL 的扩展。表继承(由 PostgreSQL 定义的形式)是非标准的。

提交更正

如果您在文档中发现任何错误,与您对特定功能的体验不符或需要进一步澄清,请使用此表格报告文档问题。