↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1

CREATE FOREIGN TABLE

CREATE FOREIGN TABLE — 定义一个新外部表

大纲

CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )
[ 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' [, ... ] ) ]

其中column_constraint为:

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

而table_constraint为:

[ CONSTRAINT constraint_name ]
{  NOT NULL column_name [ NO INHERIT ] |
   CHECK ( expression ) [ NO INHERIT ] }
[ ENFORCED | NOT ENFORCED ]

而like_option为:

{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL }

而partition_bound_spec为:

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。)

LIKE source_table [ like_option ... ] #

LIKE 子句指定一个表,新表会自动复制该表的所有列名、它们的数据类型以及非空约束。

与 INHERITS 不同,新表和原表在创建完成后即完全解耦。对原表的更改不会应用到新表,也不能在扫描原表时包含新表中的数据。

同样,与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名列或约束合并。如果在显式指定中或另一个 LIKE 子句中再次指定了同一名称,就会报错。

可选的 like_option 子句指定还要复制原表的哪些附加属性。指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。EXCLUDING 是默认值。如果对同一类对象做了多次指定,则采用最后一次。可用选项如下:

INCLUDING COMMENTS #

被复制列、约束和扩展统计信息的注释也会被复制。默认行为是不复制注释,因此新表中对应的对象将没有注释。

INCLUDING CONSTRAINTS #

会复制 CHECK 约束。列约束和表约束不作区分。非空约束始终会复制到新表。

INCLUDING DEFAULTS #

会复制被复制列定义中的默认表达式。否则默认表达式不会复制,因此新表中复制出的列默认值为 null。注意,复制会调用数据库修改函数(如 nextval)的默认值,可能在原表与新表之间建立功能上的联系。

INCLUDING GENERATED #

会复制被复制列定义中的任何生成表达式。默认情况下,新列将是普通基础列。

INCLUDING STATISTICS #

扩展统计信息将复制到新表。

INCLUDING ALL #

INCLUDING ALL 是选择所有可用单项选项的缩写形式。(可以在 INCLUDING ALL 之后再写单独的 EXCLUDING 子句,以选中除某些特定选项之外的全部选项。)

CONSTRAINT constraint_name #

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

NOT NULL [ NO INHERIT ] #

该列不允许包含空值。

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

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 | VIRTUAL ] #

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

指定 VIRTUAL 时,列会在读取时计算。(外部数据包装器会将它视为新行中的空值,并且可以选择将其存储为空值或完全忽略它。)指定 STORED 时,列会在写入时计算。(计算出的值会提供给外部数据包装器存储,并且读取时必须返回该值。)默认是 VIRTUAL。

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

server_name #

用于该外部表的现有外部服务器的名称。有关定义服务器的细节,参见 CREATE SERVER。

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

要与新外部表或其某一列关联的选项。允许的选项名和值都取决于具体的外部数据包装器,并使用该外部数据包装器的验证器函数进行验证。不允许重复的选项名(不过表选项和列选项同名是允许的)。

注解

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

某些专用的外部数据包装器可能是其所访问数据的唯一访问机制,在这种情况下,由外部数据包装器自身执行约束检查也许是合适的。但除非其文档明确说明,否则不应假定某个包装器会这样做。

尽管 PostgreSQL 不会尝试强制执行外部表上的约束,但出于查询优化的目的,它会假定这些约束是正确的。如果外部表中存在不满足已声明约束的可见行,那么对该表的查询可能会产生错误或不正确的结果。确保约束定义符合实际情况是用户的责任。

小心

当外部表被用作分区表的一个分区时,会有一个隐含约束,即其内容必须满足分区规则。同样,确保这一点是用户的责任,最好的做法是在远程服务器上安装匹配的约束。

在包含外部表分区的分区表中,如果外部数据包装器支持元组路由,那么更改分区键值的 UPDATE 可能导致某一行从本地分区移动到外部表分区。然而,目前还不能将一行从外部表分区移动到另一个分区。需要这样做的 UPDATE 会因为分区约束而失败,前提是假定远程服务器已正确强制执行该约束。

对生成列也有类似的考虑。存储型生成列会在本地 PostgreSQL 服务器上于插入或更新时计算,并交给外部数据包装器写入外部数据存储,但并不会强制要求查询外部表时返回的存储型生成列值与生成表达式保持一致。这同样可能导致不正确的查询结果。

示例

创建通过服务器 film_server 访问的外部表 films:

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;

创建通过服务器 server_07 访问的外部表 measurement_y2016m07,并将其作为范围分区表 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 定义的形式,表继承是非标准的。该命令支持的 LIKE 子句也是非标准的。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.