2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1

CREATE FOREIGN TABLE

CREATE FOREIGN TABLE — 定義一個新的外部表

概要

CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ OPTIONS ( option 'value' [, ... ] ) ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )
[ 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 [ NO INHERIT ] |
  NULL |
  CHECK ( expression ) [ NO INHERIT ] |
  DEFAULT default_expr |
  GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] }
[ ENFORCED | NOT ENFORCED ]

and table_constraint is:

[ CONSTRAINT constraint_name ]
{  NOT NULL column_name [ NO INHERIT ] |
   CHECK ( expression ) [ NO INHERIT ] }
[ ENFORCED | NOT ENFORCED ]

and like_option is:

{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL }

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 )

描述

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

要與新外部表或其某個列關聯的選項。允許的選項名稱和值特定於每個外部資料包裝器,並使用外部資料包裝器的驗證函式進行驗證。不允許重複的選項名稱(儘管表選項和列選項具有相同的名稱是可以的)。

註釋

外部表的約束(如 CHECKNOT 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 子句是非標準的。

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。