CREATE FOREIGN TABLE — 定义一个新的外部表
CREATE FOREIGN TABLE [ IF NOT EXISTS ]table_name
( [ {column_name
data_type
[ OPTIONS (option
'value
' [, ... ] ) ] [ COLLATEcollation
] [column_constraint
[ ... ] ] |table_constraint
| LIKEsource_table
[like_option
... ] } [, ... ] ] ) [ 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 [ NO INHERIT ] | NULL | CHECK (expression
) [ NO INHERIT ] | DEFAULTdefault_expr
| GENERATED ALWAYS AS (generation_expr
) [ STORED | VIRTUAL ] } [ ENFORCED | NOT ENFORCED ] andtable_constraint
is: [ CONSTRAINTconstraint_name
] { NOT NULLcolumn_name
[ NO INHERIT ] | CHECK (expression
) [ NO INHERIT ] } [ ENFORCED | NOT ENFORCED ] andlike_option
is: { INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL } 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
。)
LIKE source_table
[ like_option
... ]
LIKE
子句指定一个表,新表将自动从该表中复制所有列名、数据类型和非空约束。
与 INHERITS
不同,新表和原始表在创建完成后是完全分离的。对原始表的更改不会应用于新表,并且不可能将新表的数据包含在对原始表的扫描中。
同样与 INHERITS
不同,通过 LIKE
复制的列和约束不会与同名列和约束合并。如果显式指定或在另一个 LIKE
子句中指定了相同的名称,则会发出错误。
可选的 like_option
子句指定要从原始表中复制哪些附加属性。指定 INCLUDING
将复制属性,指定 EXCLUDING
将省略属性。EXCLUDING
是默认值。如果对同一类对象指定了多个规范,则使用最后一个。
INCLUDING COMMENTS
复制的列和约束的注释将被复制。默认行为是排除注释,导致新表中复制的列和约束没有注释。
INCLUDING CONSTRAINTS
CHECK
约束将被复制。列约束和表约束之间没有区别。非空约束始终被复制到新表中。
INCLUDING DEFAULTS
复制的列定义的默认表达式将被复制。否则,将不复制默认表达式,导致新表中复制的列具有空默认值。请注意,复制调用数据库修改函数的默认值(如 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
时,该列将在读取时计算。(外部数据包装器将在新行中将其视为 null 值,并可能选择将其存储为 null 值或完全忽略它。)当指定 STORED
时,该列将在写入时计算。(计算值将被呈现给外部数据包装器进行存储,并在读取时返回。)VIRTUAL
是默认值。
生成表达式可以引用表中的其他列,但不能引用其他生成列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。
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 定义的形式,是非标准的。本文档支持的 LIKE
子句是非标准的。
如果您在文档中发现任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。