支援的版本:目前 (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 }
    [, ... ]
] )
[ 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 |
  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 ]

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 在目前的資料庫中建立新的外部資料表。該資料表將由發出指令的使用者所擁有。

如果給定了 schema 名稱(例如,CREATE FOREIGN TABLE myschema.mytable ...),則該資料表會在指定的 schema 中建立。 否則,它會在目前的 schema 中建立。外部資料表的名稱必須與相同 schema 中的任何其他關係(資料表、序列、索引、檢視、實體化檢視或外部資料表)的名稱不同。

CREATE FOREIGN TABLE 也會自動建立一種資料類型,代表對應於外部資料表一列的複合類型。 因此,外部資料表不能與相同 schema 中的任何現有資料類型具有相同的名稱。

如果指定了 PARTITION OF 子句,則該資料表會建立為具有指定邊界的 parent_table 的分割區。

為了能夠建立外部資料表,您必須具有外部伺服器的 USAGE 權限,以及資料表中使用的所有欄位類型的 USAGE 權限。

參數

IF NOT EXISTS

如果已存在同名的關係,則不擲回錯誤。 在這種情況下,會發出通知。 請注意,無法保證現有的關係與本來會建立的關係有任何相似之處。

table_name

要建立的資料表的名稱(可選擇 schema 限定)。

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

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

注意事項

外部表格上的限制 (例如 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 定義的表格繼承是非標準的。

提交更正

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