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 整理规则
COLLATE
子句为列(其必须为可整理的数据类型)分配整理规则。如果未指定,则使用列数据类型的默认整理规则。
INHERITS ( 父表
[, ... ] )
可选的 INHERITS
子句指定新外部表从中自动继承所有列的表列表。父表可以是普通表或外部表。另请参见 CREATE TABLE
的类似形式,了解详细信息。
PARTITION OF 父表
{ FOR VALUES 分区界限说明
| DEFAULT }
此形式可用于将外部表作为具有指定分区界限值的给定父表的某一部分创建。另请参见 CREATE TABLE
的类似形式,了解详细信息。请注意,如果父表上存在 UNIQUE
索引,则当前不允许将外部表作为父表的某一部分创建。(另请参见 ALTER TABLE ATTACH PARTITION
。)
CONSTRAINT 约束名称
列或表约束的可选名称。如果约束被违反,约束名称会出现在错误消息中,因此可以像 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 ( 选项
‘值
’ [, ...] )
要与新外部数据表或其一个列关联的选项。允许的选项名称和值对于每个外部数据封装器都是特定的,并且要使用外部数据封装器的验证器函数来对它们进行验证。不允许有重复的选项名称(尽管表选项和列选项拥有相同的名称是可以的)。
外部数据表上的约束(例如 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 定义的形式)是非标准的。