CREATE FOREIGN TABLE — 定义一个新的外部表
CREATE FOREIGN TABLE [ IF NOT EXISTS ]table_name
( [ {column_name
data_type
[ OPTIONS (option
'value
' [, ... ] ) ] [ COLLATEcollation
] [column_constraint
[ ... ] ] |table_constraint
} [, ... ] ] ) [ INHERITS (parent_table
[, ... ] ) ] SERVERserver_name
[ OPTIONS (option
'value
' [, ... ] ) ] CREATE FOREIGN TABLE [ IF NOT EXISTS ]table_name
PARTITION OFparent_table
[ ( {column_name
[ WITH OPTIONS ] [column_constraint
[ ... ] ] |table_constraint
} [, ... ] ) ] { FOR VALUESpartition_bound_spec
| DEFAULT } SERVERserver_name
[ OPTIONS (option
'value
' [, ... ] ) ] wherecolumn_constraint
is: [ CONSTRAINTconstraint_name
] { NOT NULL | NULL | CHECK (expression
) [ NO INHERIT ] | DEFAULTdefault_expr
| GENERATED ALWAYS AS (generation_expr
) STORED } andtable_constraint
is: [ CONSTRAINTconstraint_name
] CHECK (expression
) [ NO INHERIT ] andpartition_bound_spec
is: IN (partition_bound_expr
[, ...] ) | FROM ( {partition_bound_expr
| MINVALUE | MAXVALUE } [, ...] ) TO ( {partition_bound_expr
| MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUSnumeric_literal
, REMAINDERnumeric_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
要用于外置表的现有外置服务器的名称。有关定义服务器的详细信息,请参见 CREATE SERVER。
OPTIONS ( option
'value
' [, ...] )
要与新外置表或其列之一关联的选项。允许的选项名称和值特定于每个外置数据封装器,并且使用外置数据封装器的验证器函数进行验证。不允许重复的选项名称(尽管表选项和列选项具有相同的名称是可以的)。
外置表上的约束(例如 CHECK
或 NOT 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 定义的形式存在的表继承是非标准的。