# 创建外表

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 }
    [, ... ]
) ] partition_bound_spec
  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 ]

# 描述

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

如果给出了模式名称(例如,创建外表 myschema.mytable ...) 然后在指定的模式中创建表。否则,它会在当前模式中创建。外部表的名称必须与同一架构中的任何其他外部表、表、序列、索引、视图或实体化视图的名称不同。

创建外表还会自动创建一个数据类型,表示对应于外表的一行的复合类型。因此,外部表不能与同一架构中的任何现有数据类型具有相同的名称。

如果分区指定子句,然后将表创建为父表有指定的界限。

为了能够创建一个外表,你必须有用法外国服务器上的特权,以及用法表中使用的所有列类型的特权。

# 参数

如果不存在

如果已存在同名关系,则不要抛出错误。在这种情况下发出通知。请注意,不能保证现有关系与已创建的关系相同。

表名

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

列名

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

数据类型

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

整理 *整理*

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

继承 ( *父表* [, ... ] )

可选的继承子句指定一个表列表,新的外部表自动从这些表中继承所有列。父表可以是普通表或外部表。见类似的形式创建表更多细节。

* 的分区父表* 价值观 *partition_bound_spec*

此表单可用于创建外部表作为具有指定分区绑定值的给定父表的分区。见类似的形式创建表更多细节。注意,目前不允许将外表创建为父表的分区,如果有的话独特父表上的索引。(也可以看看更改表附加分区.)

约束 *约束名*

列或表约束的可选名称。如果违反了约束,则约束名称出现在错误消息中,因此约束名称如col 必须为正可用于将有用的约束信息传达给客户端应用程序。(需要双引号来指定包含空格的约束名称。)如果没有指定约束名称,系统会生成一个名称。

非空

该列不允许包含空值。

空值

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

提供此子句只是为了与非标准 SQL 数据库兼容。不鼓励在新应用程序中使用它。

查看 ( *表达* ) [无继承]

查看子句指定产生布尔结果的表达式,外部表中的每一行都应满足该结果;也就是说,表达式应该为外部表中的所有行生成 TRUE 或 UNKNOWN,而不是 FALSE。指定为列约束的检查约束应仅引用该列的值,而出现在表约束中的表达式可以引用多个列。

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

标记为的约束没有继承不会传播到子表。

默认 *default_expr*

默认子句为其列定义所在的列分配默认数据值。该值是任何无变量的表达式(不允许对当前表中的其他列进行子查询和交叉引用)。默认表达式的数据类型必须与列的数据类型匹配。

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

始终生成为 ( *generation_expr* ) 已存储

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

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

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

服务器名称

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

选项 ( *选项*'*价值*' [, ...] )

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

# 笔记

对外部表的限制(例如检查非空子句)不是由核心PostgreSQL系统强制执行的,大多数外国数据包装器也不会尝试强制执行它们;也就是说,简单地假设约束为真。这种强制执行没有什么意义,因为它只适用于通过外部表插入或更新的行,而不适用于通过其他方式(例如直接在远程服务器上)修改的行。相反,附加到外部表的约束应该表示远程服务器正在实施的约束。

一些特殊用途的外部数据包装器可能是它们访问的数据的唯一访问机制,在这种情况下,外部数据包装器本身可能适合执行约束强制。但是你不应该假设包装器会这样做,除非它的文档中有这样的说明。

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

# 小心

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

在包含外部表分区的分区表中使现代化如果外部数据包装器支持元组路由,那么更改分区键值可能会导致一行从本地分区移动到外部表分区。但是,目前无法将一行从外部表分区移动到另一个分区。一使现代化这将需要这样做,因为分区约束将失败,假设远程服务器正确执行了分区约束。

类似的考虑也适用于生成的列。存储的生成列在本地PostgreSQL server上的insert或update时计算,并交给外部数据包装器以写入外部数据存储,但不强制要求外部表的查询为存储的生成列返回与生成表达式一致的值。同样,这可能会导致错误的查询结果。

# 例子

创建外部表电影,将通过服务器访问电影服务器:

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;

创建外部表测量_Y2016 M07,将通过服务器访问服务器_07,作为范围分区表的分区测量:

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

# 兼容性

这个创建外部表命令在很大程度上符合SQL标准;然而,就像创建表格, 无效的允许使用约束和零列外部表。指定列默认值的能力也是PostgreSQL的一个扩展。PostgreSQL定义的表继承是非标准的。

# 另见

更改外国表格, 放下外国桌子, 创建表格, 创建服务器, 导入外部模式