Postgresql 中文操作指南

CREATE FOREIGN TABLE

CREATE FOREIGN TABLE — 定义新外部表

Synopsis

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 )

Description

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

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

CREATE FOREIGN TABLE 还自动创建一种数据类型,该类型表示与外部表一行相对应的复合类型。因此,外部表不能与同一架构中的任何现有数据类型同名。

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

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

Parameters

  • IF NOT EXISTS

    • 如果某个同名关系已经存在,则不要抛出错误。在这种情况下会发出通知。请注意,无法保证现有关系与将要创建的关系完全一样。

  • table_name

    • 要创建的表名(可选地经过架构限定)。

  • column_name

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

  • data_type

    • 该列的数据类型。这可以包括数组说明符。有关 PostgreSQL 支持的数据类型了解更多信息,请参阅 Chapter 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 子句为其列定义所在的列分配默认数据值。该值是任何无变量表达式(不允许子查询和对当前表中其他列的交叉引用)。默认表达式的类型必须与该列的数据类型匹配。

    • 对于任何未为该列指定值的插入操作,将使用默认表达式。如果某列没有默认值,那么该默认值为空。

  • GENERATED ALWAYS AS ( _generation_expr ) STORED_

    • 此子句将该列创建为 generated column 。该列无法写入,而在读取时将会返回指定表达式的结果。

    • 必需使用关键字 STORED 来表示该列将在写入时计算。(计算值将呈现给外部数据包装器以进行存储,并且必须在读取时返回。)

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

  • server_name

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

  • OPTIONS ( _option ' value ' [, …​] )_

    • 要与新外部表或其列之一关联的选项。允许的选项名称和值因各外部数据封装器而异,并且使用外部数据封装器的验证器函数进行验证。不允许重复的选项名称(尽管表选项和列选项具有相同名称是可以的)。

Notes

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

一些特殊用途的外部数据封装器可能是其访问数据时唯一的访问机制,在这种情况下,由外部数据封装器本身执行约束强制可能是合适的。但是,您不应该假定封装器会这样做,除非其文档中这么说。

尽管 PostgreSQL 不会尝试强制执行外部表上的约束,但它确实假设它们对于查询优化而言是正确的。如果外部表中可见的行不满足已声明的约束,则对该表的查询可能会产生错误或不正确的答案。确保约束定义与现实相匹配是用户的责任。

Caution

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

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

类似的考虑因素也适用于已生成列。存储的已生成列是在本地 PostgreSQL 服务器上插入或更新时计算出的,并传递给外部数据封装器以写入外部数据存储,但并不要求外部表查询返回的值对于已存储的已生成列与生成表达式一致。同样,这可能会导致错误的查询结果。

Examples

创建外部表 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;

Compatibility

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