支援的版本: 目前 (17) / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

CREATE TABLE

CREATE TABLE — 定義一個新的資料表

概要

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    OF type_name [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    PARTITION OF parent_table [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ] { FOR VALUES partition_bound_spec | DEFAULT }
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL |
  NULL |
  CHECK ( expression ) [ NO INHERIT ] |
  DEFAULT default_expr |
  GENERATED ALWAYS AS ( generation_expr ) STORED |
  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters |
  PRIMARY KEY index_parameters |
  REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

and table_constraint is:

[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) [ NO INHERIT ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters |
  PRIMARY KEY ( column_name [, ... ] ) index_parameters |
  EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
  FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

and like_option is:

{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | 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 )

index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:

[ INCLUDE ( column_name [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ USING INDEX TABLESPACE tablespace_name ]

exclude_element in an EXCLUDE constraint is:

{ column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

referential_action in a FOREIGN KEY/REFERENCES constraint is:

{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] }

描述

CREATE TABLE 將會在目前的資料庫中建立一個新的、初始為空的資料表。此資料表將會由發出此指令的使用者所擁有。

如果指定了結構描述名稱(例如,CREATE TABLE myschema.mytable ...),則會在指定的結構描述中建立資料表。 否則,它會在目前的結構描述中建立。 暫存資料表存在於一個特殊的結構描述中,因此在建立暫存資料表時不能指定結構描述名稱。 資料表的名稱必須與相同結構描述中的任何其他關聯(資料表、序列、索引、檢視表、實體化檢視表或外部資料表)的名稱不同。

CREATE TABLE 也會自動建立一個資料類型,該資料類型代表與資料表的一列對應的複合類型。 因此,資料表的名稱不能與相同結構描述中的任何現有資料類型相同。

可選的約束子句指定約束(測試),新的或更新的列必須滿足這些約束,插入或更新操作才能成功。 約束是一個 SQL 物件,有助於以各種方式定義資料表中的有效值集合。

有兩種定義約束的方式:資料表約束和欄位約束。 欄位約束定義為欄位定義的一部分。 資料表約束定義不與特定的欄位相關聯,並且它可以包含多個欄位。 每個欄位約束也可以寫為資料表約束; 欄位約束僅是一種符號上的便利,用於約束僅影響一個欄位時。

為了能夠建立資料表,您必須對所有欄位類型或 OF 子句中的類型具有 USAGE 權限。

參數

TEMPORARYTEMP #

如果指定,則將資料表建立為暫存資料表。 暫存資料表會在會話結束時自動刪除,或者也可以在目前交易結束時刪除(請參閱下面的 ON COMMIT)。 預設的 search_path 首先包含暫存結構描述,因此,在暫存資料表存在期間,不會為新的計畫選擇相同名稱的現有永久資料表,除非使用結構描述限定名稱引用它們。 在暫存資料表上建立的任何索引也會自動成為暫存索引。

autovacuum 精靈無法存取,因此無法清理或分析暫存資料表。 因此,應透過會話 SQL 指令執行適當的清理和分析操作。 例如,如果要將暫存資料表用於複雜的查詢,建議在填入暫存資料表後,對其執行 ANALYZE

可選擇在 TEMPORARYTEMP 之前寫入 GLOBALLOCAL。 這目前在 PostgreSQL 中沒有任何區別,並且已被棄用; 請參閱下面的 相容性

UNLOGGED #

如果指定,則將資料表建立為未記錄的資料表。 寫入未記錄資料表的資料不會寫入預寫式記錄(請參閱第 28 章),這使得它們比普通資料表快得多。 但是,它們不是崩潰安全的:未記錄的資料表會在崩潰或不乾淨的關機後自動截斷。 未記錄資料表的內容也不會複寫到備用伺服器。 在未記錄資料表上建立的任何索引也會自動成為未記錄索引。

如果指定此選項,則與未記錄資料表一起建立的任何序列(用於識別或序列欄位)也會建立為未記錄序列。

IF NOT EXISTS #

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

table_name #

要建立的資料表名稱(可選擇使用結構描述限定)。

OF type_name #

建立一個類型資料表,該資料表從指定的複合類型(名稱可選擇使用結構描述限定)獲取其結構。 類型資料表與其類型相關聯; 例如,如果刪除該類型(使用 DROP TYPE ... CASCADE),則該資料表將被刪除。

建立類型資料表時,欄位的資料類型由基礎複合類型確定,而不是由 CREATE TABLE 指令指定。 但是,CREATE TABLE 指令可以將預設值和約束新增到資料表,並且可以指定儲存參數。

column_name #

要在新資料表中建立的欄位名稱。

data_type #

欄位的資料類型。這可以包含陣列指定符。關於 PostgreSQL 支援的資料類型之更多資訊,請參考第 8 章

COLLATE collation #

COLLATE 子句會將排序規則指派給欄位(欄位必須是可排序的資料類型)。如果未指定,則會使用欄位資料類型的預設排序規則。

STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } #

此形式設定欄位的儲存模式。這控制是否將此欄位保留在行內或輔助TOAST表中,以及是否應壓縮資料。PLAIN 必須用於固定長度的值,例如 integer,並且是行內、未壓縮的。MAIN 用於行內、可壓縮的資料。EXTERNAL 用於外部、未壓縮的資料,而 EXTENDED 用於外部、壓縮的資料。寫入 DEFAULT 會將儲存模式設定為欄位資料類型的預設模式。EXTENDED 是大多數支援非 PLAIN 儲存之資料類型的預設值。使用 EXTERNAL 將使對非常大的 textbytea 值進行子字串操作的速度更快,但會增加儲存空間。請參閱 第 65.2 節以取得更多資訊。

COMPRESSION compression_method #

COMPRESSION 子句設定欄位的壓縮方法。僅可變寬度資料類型支援壓縮,並且僅當欄位的儲存模式為 mainextended 時才使用壓縮。(請參閱 ALTER TABLE 以取得有關欄位儲存模式的資訊。)為分割資料表設定此屬性沒有直接效果,因為此類資料表沒有自己的儲存空間,但是配置的值將由新建立的分割繼承。支援的壓縮方法為 pglzlz4。(僅當在建置 PostgreSQL 時使用 --with-lz4 時,lz4 才可用。)此外,compression_method 可以是 default,以明確指定預設行為,即在插入資料時查詢 default_toast_compression 設定以確定要使用的方法。

INHERITS ( parent_table [, ... ] ) #

可選的 INHERITS 子句指定一個資料表清單,新資料表會自動從中繼承所有欄位。父資料表可以是普通資料表或外部資料表。

使用 INHERITS 會在新子資料表及其父資料表之間建立持久關係。對父資料表進行的結構描述修改通常也會傳播到子資料表,並且預設情況下,子資料表的資料會包含在父資料表的掃描中。

如果多個父資料表中存在相同的欄位名稱,則會報告錯誤,除非每個父資料表中欄位的資料類型相符。如果沒有衝突,則會合併重複的欄位以在新資料表中形成單個欄位。如果新資料表的欄位名稱清單包含也已繼承的欄位名稱,則資料類型也必須與繼承的欄位相符,並且欄位定義會合併為一個。如果新資料表明確為欄位指定預設值,則此預設值會覆蓋從欄位的繼承宣告中繼承的任何預設值。否則,指定欄位預設值的任何父資料表都必須指定相同的預設值,否則會報告錯誤。

CHECK 限制條件的合併方式與欄位基本相同:如果多個父資料表和/或新資料表定義包含相同名稱的 CHECK 限制條件,則這些限制條件必須都具有相同的檢查運算式,否則會報告錯誤。具有相同名稱和運算式的限制條件將合併為一個副本。在父資料表中標記為 NO INHERIT 的限制條件將不予考慮。請注意,新資料表中未命名的 CHECK 限制條件永遠不會合併,因為始終會為其選擇一個唯一的名稱。

欄位 STORAGE 設定也會從父資料表複製。

如果父資料表中的欄位是識別欄位,則不會繼承該屬性。如果需要,可以在子資料表中將欄位宣告為識別欄位。

PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) #

可選的 PARTITION BY 子句指定分割資料表的策略。因此建立的資料表稱為分割資料表。括在括號中的欄位或運算式清單構成資料表的分割鍵。使用範圍或雜湊分割時,分割鍵可以包含多個欄位或運算式(最多 32 個,但是可以在建置 PostgreSQL 時更改此限制),但是對於清單分割,分割鍵必須包含單個欄位或運算式。

範圍和清單分割需要 btree 運算子類別,而雜湊分割需要雜湊運算子類別。如果未明確指定運算子類別,則將使用相應類型的預設運算子類別;如果不存在預設運算子類別,則會引發錯誤。使用雜湊分割時,所使用的運算子類別必須實作支援函數 2(有關詳細資訊,請參閱第 36.16.3 節)。

分割資料表分為子資料表(稱為分割),這些子資料表使用單獨的 CREATE TABLE 命令建立。分割資料表本身是空的。插入到資料表中的資料列會根據分割鍵中欄位或運算式的值路由到分割。如果沒有現有的分割與新資料列中的值相符,則會報告錯誤。

分割表不支援 EXCLUDE 限制;但是,您可以在個別分割區上定義這些限制。

有關表格分割的更多討論,請參閱第 5.12 節

PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } #

將表格建立為指定父表格的分割區。表格可以使用 FOR VALUES 建立為特定值的分割區,或者使用 DEFAULT 建立為預設分割區。存在於父表格中的任何索引、限制和使用者定義的列層級觸發器都會複製到新的分割區。

partition_bound_spec 必須對應於父表格的分割方法和分割鍵,並且不得與該父表格的任何現有分割區重疊。具有 IN 的形式用於清單分割,具有 FROMTO 的形式用於範圍分割,而具有 WITH 的形式用於雜湊分割。

partition_bound_expr 是任何不包含變數的表達式(不允許子查詢、視窗函數、聚合函數和傳回集合的函數)。其資料類型必須與對應的分割鍵欄位的資料類型相符。該表達式在建立表格時評估一次,因此它甚至可以包含諸如 CURRENT_TIMESTAMP 之類的不穩定表達式。

建立清單分割區時,可以指定 NULL 以表示分割區允許分割鍵欄位為空值。但是,給定父表格不能有多個這樣的清單分割區。不能為範圍分割區指定 NULL

建立範圍分割區時,以 FROM 指定的下限是包含性邊界,而以 TO 指定的上限是排除性邊界。也就是說,FROM 清單中指定的值是此分割區的對應分割鍵欄位的有效值,而 TO 清單中的值則不是。請注意,此陳述必須根據逐列比較的規則理解(請參閱第 9.25.5 節)。例如,假設給定 PARTITION BY RANGE (x,y),分割區邊界 FROM (1, 2) TO (3, 4) 允許 x=1 且任何 y>=2x=2 且任何非空值 y 以及 x=3 且任何 y<4

在建立範圍分割區時,可以使用特殊值 MINVALUEMAXVALUE 來指示欄位的值沒有下限或上限。例如,使用 FROM (MINVALUE) TO (10) 定義的分割區允許任何小於 10 的值,而使用 FROM (10) TO (MAXVALUE) 定義的分割區允許任何大於或等於 10 的值。

在建立涉及多個欄位的範圍分割區時,也可以合理地將 MAXVALUE 用作下限的一部分,並將 MINVALUE 用作上限的一部分。例如,使用 FROM (0, MAXVALUE) TO (10, MAXVALUE) 定義的分割區允許第一個分割鍵欄位大於 0 且小於或等於 10 的任何列。同樣,使用 FROM ('a', MINVALUE) TO ('b', MINVALUE) 定義的分割區允許第一個分割鍵欄位以 "a" 開頭的任何列。

請注意,如果 MINVALUEMAXVALUE 用於分割邊界的一個欄位,則必須對所有後續欄位使用相同的值。例如,(10, MINVALUE, 0) 不是有效的邊界;您應該寫入 (10, MINVALUE, MINVALUE)

另請注意,某些元素類型(例如 timestamp)具有“無限”的概念,這只是可以儲存的另一個值。這與 MINVALUEMAXVALUE 不同,它們不是可以儲存的真實值,而是表示該值是無界的。可以認為 MAXVALUE 大於任何其他值,包括“無限”,而 MINVALUE 小於任何其他值,包括“負無限”。因此,範圍 FROM ('infinity') TO (MAXVALUE) 不是空範圍;它只允許儲存一個值 - "infinity"。

如果指定了 DEFAULT,則會將表格建立為父表格的預設分割區。此選項不適用於雜湊分割表。不適合給定父表格的任何其他分割區的分割鍵值將會被路由到預設分割區。

當表格具有現有的 DEFAULT 分割區並且向其新增新的分割區時,必須掃描預設分割區,以驗證它不包含任何屬於新分割區的列。如果預設分割區包含大量列,這可能會很慢。如果預設分割區是外部表格,或者它具有證明它不能包含應放置在新分割區中的列的限制,則將跳過掃描。

建立雜湊分割區時,必須指定模數和餘數。模數必須為正整數,餘數必須為小於模數的非負整數。通常,在最初設定雜湊分割表時,您應該選擇一個等於分割區數量的模數,並為每個表格分配相同的模數和不同的餘數(請參閱下面的範例)。但是,並非要求每個分割區都具有相同的模數,僅要求雜湊分割表的分割區中出現的每個模數都是下一個較大模數的因數。這允許以遞增方式增加分割區的數量,而無需一次移動所有資料。例如,假設您有一個具有 8 個分割區的雜湊分割表,每個分割區的模數為 8,但發現有必要將分割區的數量增加到 16。您可以分離其中一個模數為 8 的分割區,建立兩個新的模數為 16 的分割區,它們覆蓋相同部分的鍵空間(一個的餘數等於分離分割區的餘數,另一個的餘數等於該值加上 8),並用資料重新填入它們。然後,您可以對每個模數為 8 的分割區重複此操作(可能在稍後的時間),直到沒有剩餘的分割區。雖然這可能仍然涉及每個步驟的大量資料移動,但仍然比必須建立一個全新的表格並一次移動所有資料要好。

分割區必須具有與它所屬的分割表格相同的欄位名稱和類型。對分割表格的欄位名稱或類型的修改將自動傳播到所有分割區。CHECK 限制將自動被每個分割區繼承,但個別分割區可以指定額外的 CHECK 限制;與父表格中具有相同名稱和條件的額外限制將與父限制合併。可以為每個分割區單獨指定預設值。但請注意,當透過分割表格插入元組時,不會套用分割區的預設值。

插入到分割表格中的列將自動路由到正確的分割區。如果不存在合適的分割區,則會發生錯誤。

通常會影響表格及其所有繼承子項目的操作(例如 TRUNCATE)會階聯到所有分割區,但也可以在個別分割區上執行。

請注意,使用 PARTITION OF 建立分割區需要在父分割表上取得 ACCESS EXCLUSIVE 鎖定。同樣地,使用 DROP TABLE 刪除分割區需要在父表上取得 ACCESS EXCLUSIVE 鎖定。可以使用 ALTER TABLE ATTACH/DETACH PARTITION 以較弱的鎖定來執行這些操作,從而減少對分割表上並行操作的干擾。

LIKE source_table [ like_option ... ] #

LIKE 子句指定一個表格,新表格會自動從該表格複製所有欄位名稱、資料類型和非空約束。

INHERITS 不同,新表格和原始表格在建立完成後完全分離。對原始表格的變更不會應用於新表格,並且無法在掃描原始表格時包含新表格的資料。

同樣與 INHERITS 不同的是,由 LIKE 複製的欄位和約束不會與類似名稱的欄位和約束合併。如果明確指定了相同的名稱,或在另一個 LIKE 子句中指定,則會發出錯誤訊號。

可選的 like_option 子句指定要複製的原始表格的其他屬性。指定 INCLUDING 會複製該屬性,指定 EXCLUDING 會省略該屬性。EXCLUDING 是預設值。如果對同一種類型的物件進行多個指定,則使用最後一個。可用的選項如下:

INCLUDING COMMENTS #

將複製複製的欄位、約束和索引的註解。預設行為是排除註解,導致新表格中複製的欄位和約束沒有註解。

INCLUDING COMPRESSION #

將複製欄位的壓縮方法。預設行為是排除壓縮方法,導致欄位具有預設壓縮方法。

INCLUDING CONSTRAINTS #

將複製 CHECK 約束。欄位約束和表格約束之間沒有區別。非空約束始終複製到新表格。

INCLUDING DEFAULTS #

將複製複製的欄位定義的預設表達式。否則,不複製預設表達式,導致新表格中複製的欄位具有空值預設值。請注意,複製呼叫資料庫修改函數 (例如 nextval) 的預設值可能會在原始表格和新表格之間建立功能連結。

INCLUDING GENERATED #

將複製複製的欄位定義的任何產生表達式。預設情況下,新欄位將是常規的基礎欄位。

INCLUDING IDENTITY #

將複製複製的欄位定義的任何身分規格。會為新表格的每個身分欄位建立一個新的序列,與舊表格相關聯的序列分開。

INCLUDING INDEXES #

將在原始表格上建立索引、PRIMARY KEYUNIQUEEXCLUDE 約束到新表格上。新索引和約束的名稱會根據預設規則選擇,無論原始索引和約束的命名方式如何。(此行為避免了新索引可能發生的重複名稱失敗。)

INCLUDING STATISTICS #

擴展統計資訊會複製到新表格。

INCLUDING STORAGE #

將複製複製的欄位定義的 STORAGE 設定。預設行為是排除 STORAGE 設定,導致新表格中複製的欄位具有特定於類型的預設設定。有關 STORAGE 設定的更多資訊,請參閱 第 65.2 節

INCLUDING ALL #

INCLUDING ALL 是選擇所有可用個別選項的縮寫形式。(在 INCLUDING ALL 之後撰寫個別的 EXCLUDING 子句以選擇除某些特定選項之外的所有選項可能很有用。)

LIKE 子句還可用於從檢視表、外部表格或複合類型複製欄位定義。不適用的選項(例如,從檢視表複製 INCLUDING INDEXES)會被忽略。

CONSTRAINT constraint_name #

欄位或表格約束的可選名稱。如果違反約束,錯誤訊息中會顯示約束名稱,因此可以使用類似 col must be positive 的約束名稱向用戶端應用程式傳達有用的約束資訊。(需要使用雙引號來指定包含空格的約束名稱。)如果未指定約束名稱,系統會產生一個名稱。

NOT NULL #

不允許欄位包含空值。

NULL #

允許欄位包含空值。這是預設值。

提供此子句僅為與非標準 SQL 資料庫相容。不建議在新應用程式中使用。

CHECK ( expression ) [ NO INHERIT ] #

CHECK 子句指定一個產生布林結果的表達式,新的或更新的列必須滿足該表達式,插入或更新操作才能成功。評估為 TRUE 或 UNKNOWN 的表達式會成功。如果插入或更新操作的任何列產生 FALSE 結果,則會引發錯誤例外,並且插入或更新不會變更資料庫。指定為欄位約束的檢查約束應僅參考該欄位的值,而表格約束中出現的表達式可以參考多個欄位。

目前,CHECK 運算式不能包含子查詢,也不能引用目前列的欄位以外的變數(請參閱第 5.5.1 節)。可以引用系統欄位 tableoid,但不能引用任何其他系統欄位。

標記為 NO INHERIT 的約束條件不會傳播到子資料表。

當一個資料表有多個 CHECK 約束條件時,將在檢查 NOT NULL 約束條件後,按名稱的字母順序對每一列進行測試。(9.5 之前的 PostgreSQL 版本不保證 CHECK 約束條件的觸發順序。)

DEFAULT 預設運算式 #

DEFAULT 子句會為其欄位定義中出現的欄位指定預設資料值。該值可以是任何無變數的運算式(特別是不允許交叉引用目前資料表中的其他欄位)。也不允許使用子查詢。預設運算式的資料類型必須與欄位的資料類型相符。

如果任何插入操作沒有為欄位指定值,則將使用預設運算式。如果欄位沒有預設值,則預設值為 null。

GENERATED ALWAYS AS ( 產生運算式 ) STORED #

此子句會將欄位建立為產生欄位。欄位無法寫入,並且在讀取時將傳回指定運算式的結果。

必須使用關鍵字 STORED 來表示該欄位將在寫入時計算並儲存在磁碟上。

產生運算式可以引用資料表中的其他欄位,但不能引用其他產生欄位。使用的任何函數和運算子都必須是不可變的。不允許引用其他資料表。

GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( 序列選項 ) ] #

此子句會將欄位建立為識別欄位。它將附加一個隱含的序列,並且在新插入的列中,該欄位將自動從序列中分配值。這樣的欄位隱含地具有 NOT NULL

ALWAYSBY DEFAULT 子句決定了在 INSERTUPDATE 指令中如何處理使用者明確指定的值。

INSERT 指令中,如果選擇了 ALWAYS,則只有當 INSERT 語句指定 OVERRIDING SYSTEM VALUE 時,才會接受使用者指定的值。 如果選擇了 BY DEFAULT,則使用者指定的值優先。 有關詳細信息,請參閱 INSERT。(在 COPY 指令中,無論此設定如何,始終使用使用者指定的值。)

UPDATE 指令中,如果選擇了 ALWAYS,則拒絕將欄位更新為 DEFAULT 以外的任何值。如果選擇了 BY DEFAULT,則可以正常更新欄位。(UPDATE 指令沒有 OVERRIDING 子句。)

可選的 序列選項 子句可用於覆寫序列的參數。 可用的選項包括 CREATE SEQUENCE 中顯示的選項,以及 SEQUENCE NAME 名稱LOGGEDUNLOGGED,這些選項允許選擇序列的名稱和持久性級別。 如果沒有 SEQUENCE NAME,系統會為序列選擇一個未使用的名稱。 如果沒有 LOGGEDUNLOGGED,序列將具有與資料表相同的持久性級別。

UNIQUE [ NULLS [ NOT ] DISTINCT ] (欄位約束條件)
UNIQUE [ NULLS [ NOT ] DISTINCT ] ( 欄位名稱 [, ... ] ) [ INCLUDE ( 欄位名稱 [, ...]) ] (資料表約束條件) #

UNIQUE 約束條件指定資料表的一個或多個欄位的群組只能包含唯一值。唯一資料表約束條件的行為與唯一欄位約束條件的行為相同,但額外具有跨越多個欄位的功能。因此,該約束條件會強制執行任何兩個列必須在至少一個欄位中有所不同。

為了唯一約束條件的目的,除非指定 NULLS NOT DISTINCT,否則 null 值不被視為相等。

每個唯一約束條件都應命名一組欄位,該組欄位與為資料表定義的任何其他唯一或主鍵約束條件命名的欄位組不同。(否則,多餘的唯一約束條件將被丟棄。)

當為多層分割階層建立唯一約束條件時,目標分割資料表及其所有子代分割資料表的分割鍵中的所有欄位都必須包含在約束條件定義中。

新增唯一約束條件將自動在約束條件中使用的欄位或欄位群組上建立唯一 btree 索引。建立的索引與唯一約束條件具有相同的名稱。

可選的 INCLUDE 子句會向該索引新增一個或多個僅僅是有效負載的欄位:不會對它們強制執行唯一性,並且無法根據這些欄位搜尋索引。 但是,它們可以由僅索引掃描檢索。 請注意,儘管不會對包含的欄位強制執行約束條件,但它仍然依賴於它們。 因此,對這些欄位的一些操作(例如,DROP COLUMN)可能會導致級聯約束條件和索引刪除。

PRIMARY KEY (欄位約束條件)
PRIMARY KEY ( 欄位名稱 [, ... ] ) [ INCLUDE ( 欄位名稱 [, ...]) ] (資料表約束條件) #

PRIMARY KEY 約束條件指定資料表的一個或多個欄位只能包含唯一(非重複)、非空值。 一個資料表只能指定一個主鍵,無論是作為欄位約束條件還是資料表約束條件。

主鍵約束條件應命名一組欄位,該組欄位與為同一資料表定義的任何唯一約束條件命名的欄位組不同。(否則,唯一約束條件是多餘的,將被丟棄。)

PRIMARY KEY 強制執行與 UNIQUENOT NULL 組合相同的資料約束條件。 但是,將一組欄位識別為主鍵也提供了有關結構描述設計的中繼資料,因為主鍵表示其他資料表可以依賴此組欄位作為列的唯一識別碼。

放置在分割資料表上時,PRIMARY KEY 約束條件會共用先前針對 UNIQUE 約束條件描述的限制。

加入 PRIMARY KEY 限制條件會自動在限制條件中使用的欄位或欄位群組上建立唯一的 btree 索引。該索引的名稱與主鍵限制條件相同。

可選的 INCLUDE 子句會向該索引新增一個或多個僅僅是有效負載的欄位:不會對它們強制執行唯一性,並且無法根據這些欄位搜尋索引。 但是,它們可以由僅索引掃描檢索。 請注意,儘管不會對包含的欄位強制執行約束條件,但它仍然依賴於它們。 因此,對這些欄位的一些操作(例如,DROP COLUMN)可能會導致級聯約束條件和索引刪除。

EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] #

EXCLUDE 子句定義一個排除限制條件,它保證如果使用指定的運算子比較任何兩列的指定欄位或表達式,則並非所有這些比較都會傳回 TRUE。如果所有指定的運算子都測試相等性,則這相當於 UNIQUE 限制條件,儘管普通的唯一限制條件會更快。但是,排除限制條件可以指定比簡單相等性更通用的限制條件。例如,您可以使用 && 運算子指定一個限制條件,即表格中沒有兩列包含重疊的圓圈(請參閱第 8.8 節)。運算子必須是可交換的。

排除限制條件是使用與限制條件同名的索引來實現的,因此每個指定的運算子都必須與索引存取方法 index_method 的適當運算子類別相關聯(請參閱第 11.10 節)。每個 exclude_element 定義索引的一個欄位,因此它可以選擇性地指定排序規則、運算子類別、運算子類別參數和/或排序選項;這些在CREATE INDEX下有完整描述。

存取方法必須支援 amgettuple(請參閱第 62 章);目前這意味著GIN無法使用。 雖然允許,但使用帶有排除限制條件的 B-tree 或雜湊索引意義不大,因為這並不能比普通的唯一限制條件做得更好。 所以實際上,存取方法將始終是GiSTSP-GiST.

predicate 允許您在表格的子集上指定排除限制條件; 在內部,這會建立一個部分索引。 請注意,述詞周圍需要括號。

REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] (欄位限制條件)
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] (表格限制條件) #

這些子句指定一個外鍵限制條件,它要求新表格的一個或多個欄位群組必須僅包含與參考表格的某些列的參考欄位中的值相符的值。如果省略了 refcolumn 列表,則使用 reftable 的主鍵。否則,refcolumn 列表必須引用非可延遲唯一或主鍵限制條件的欄位,或是非部分唯一索引的欄位。使用者必須對參考表格(整個表格或特定的參考欄位)具有 REFERENCES 權限。加入外鍵限制條件需要對參考表格取得 SHARE ROW EXCLUSIVE 鎖定。請注意,不能在暫存表格和永久表格之間定義外鍵限制條件。

使用給定的相符類型,將插入到參考欄位中的值與參考表格和參考欄位的值進行比對。有三種相符類型:MATCH FULLMATCH PARTIALMATCH SIMPLE(這是預設值)。MATCH FULL 不允許多欄位外鍵的一欄為空,除非所有外鍵欄位都為空;如果它們都為空,則不需要參考表格中具有相符列。MATCH SIMPLE 允許任何外鍵欄位為空;如果它們中的任何一個為空,則不需要參考表格中具有相符列。MATCH PARTIAL 尚未實作。(當然,可以將 NOT NULL 限制條件套用至參考欄位,以防止這些情況發生。)

此外,當參考欄位中的資料變更時,會對此表格的欄位中的資料執行某些動作。ON DELETE 子句指定在參考表格中的參考列被刪除時要執行的動作。同樣地,ON UPDATE 子句指定在參考表格中的參考欄位更新為新值時要執行的動作。如果更新了列,但參考欄位實際上並未變更,則不會執行任何動作。除了 NO ACTION 檢查之外,參考動作無法延遲,即使限制條件宣告為可延遲。

NO ACTION #

產生一個錯誤,指示刪除或更新會產生外鍵限制條件衝突。如果限制條件已延遲,則如果仍然存在任何參考列,將在限制條件檢查時產生此錯誤。這是預設動作。

RESTRICT #

產生一個錯誤,指示刪除或更新會產生外鍵限制條件衝突。這與 NO ACTION 相同,只是檢查不可延遲。

CASCADE #

刪除任何參考已刪除列的列,或分別將參考欄位的值更新為參考欄位的新值。

SET NULL [ ( column_name [, ... ] ) ] #

將所有參考欄位,或參考欄位的指定子集,設定為 null。 只能為 ON DELETE 動作指定欄位的子集。

SET DEFAULT [ ( column_name [, ... ] ) ] #

將所有參考欄位,或參考欄位的指定子集,設定為其預設值。 只能為 ON DELETE 動作指定欄位的子集。(如果預設值不是 null,則參考表格中必須存在與預設值相符的列,否則操作將會失敗。)

如果參考欄位經常變更,建議在參考欄位上新增索引,以便更有效率地執行與外部鍵約束相關的參考動作。

DEFERRABLE
NOT DEFERRABLE #

這控制是否可以延遲約束。 無法延遲的約束將在每個指令後立即檢查。 可以使用 SET CONSTRAINTS 指令將可延遲約束的檢查延遲到交易結束時。NOT DEFERRABLE 是預設值。 目前,只有 UNIQUEPRIMARY KEYEXCLUDEREFERENCES (外部鍵) 約束接受此子句。 NOT NULLCHECK 約束是不可延遲的。 請注意,在包含 ON CONFLICT DO UPDATE 子句的 INSERT 語句中,可延遲約束不能用作衝突仲裁者。

INITIALLY IMMEDIATE
INITIALLY DEFERRED #

如果約束是可延遲的,則此子句指定檢查約束的預設時間。 如果約束是 INITIALLY IMMEDIATE,則在每個語句之後都會檢查它。 這是預設值。 如果約束是 INITIALLY DEFERRED,則僅在交易結束時檢查它。 可以使用 SET CONSTRAINTS 指令變更約束檢查時間。

USING method #

這個可選子句指定用於儲存新表格內容的表格存取方法;該方法需要是 TABLE 類型的存取方法。 參閱 第 61 章 獲取更多資訊。 如果未指定此選項,則為新表格選擇預設表格存取方法。 有關更多資訊,請參閱 default_table_access_method

建立分割區時,如果設定了表格存取方法,則表格存取方法是其已分割表格的存取方法。

WITH ( storage_parameter [= value] [, ... ] ) #

此子句指定表格或索引的可選儲存參數;有關更多資訊,請參閱下面的儲存參數。 為了向後相容性,表格的 WITH 子句也可以包含 OIDS=FALSE,以指定新表格的列不應包含 OID(物件識別碼),不再支援 OIDS=TRUE

WITHOUT OIDS #

這是宣告表格 WITHOUT OIDS 的向後相容語法,不再支援建立 WITH OIDS 表格。

ON COMMIT #

可以使用 ON COMMIT 控制交易區塊結束時暫存表格的行為。 三個選項是

PRESERVE ROWS #

在交易結束時不採取特殊動作。 這是預設行為。

DELETE ROWS #

每個交易區塊結束時,將刪除暫存表格中的所有列。 實質上,每次提交時都會執行自動 TRUNCATE。 當在已分割表格上使用時,不會將其串聯到其分割區。

DROP #

在目前交易區塊結束時,將捨棄暫存表格。 當在已分割表格上使用時,此動作會捨棄其分割區;當在具有繼承子系的表格上使用時,會捨棄相關的子系。

TABLESPACE tablespace_name #

tablespace_name 是要在其中建立新表格的表格空間名稱。 如果未指定,則會參考 default_tablespace,如果表格是暫存表格,則會參考 temp_tablespaces。 對於已分割表格,由於表格本身不需要儲存空間,因此指定的表格空間會覆蓋 default_tablespace,作為在未明確指定其他表格空間時,用於任何新建立的分割區的預設表格空間。

USING INDEX TABLESPACE tablespace_name #

此子句允許選擇將建立與 UNIQUEPRIMARY KEYEXCLUDE 約束相關聯的索引的表格空間。 如果未指定,則會參考 default_tablespace,如果表格是暫存表格,則會參考 temp_tablespaces

儲存參數

WITH 子句可以為表格以及與 UNIQUEPRIMARY KEYEXCLUDE 約束相關聯的索引指定儲存參數。 索引的儲存參數記錄在 CREATE INDEX 中。 下面列出了目前可用於表格的儲存參數。 對於許多這些參數,如所示,還有一個具有相同名稱但以 toast. 為字首的額外參數,它控制表格的輔助行為TOASTtable,如果有的話(關於 TOAST 的更多資訊,請參閱第 65.2 節)。如果設定了 table 參數值,但沒有設定對應的 toast. 參數,則 TOAST table 將使用 table 的參數值。不支援為分割表指定這些參數,但可以為個別的葉分割區指定它們。

fillfactor (integer) #

table 的 fillfactor 是一個介於 10 到 100 之間的百分比。100(完全填滿)是預設值。如果指定了較小的 fillfactor,INSERT 操作只會將 table 頁面填滿到指定的百分比;每個頁面上剩餘的空間將保留用於更新該頁面上的資料列。這讓 UPDATE 有機會將資料列的更新副本放置在與原始資料列相同的頁面上,這比將其放置在不同的頁面上更有效率,並使僅堆積元組更新更有可能發生。對於從未更新過的 table,完全填滿是最佳選擇,但在經常更新的 table 中,較小的 fillfactor 更為合適。此參數不能為 TOAST table 設定。

toast_tuple_target (integer) #

toast_tuple_target 指定在我們嘗試壓縮和/或將長欄位值移動到 TOAST table 中之前所需的最小元組長度,並且也是 toasted 開始後我們嘗試將長度縮短到的目標長度。這會影響標記為 External(用於移動)、Main(用於壓縮)或 Extended(用於兩者)的欄位,並且僅適用於新的元組。對現有的資料列沒有影響。預設情況下,此參數設定為允許每個區塊至少 4 個元組,在預設區塊大小下為 2040 位元組。有效值介於 128 位元組和 (區塊大小 - 標頭) 之間,預設為 8160 位元組。更改此值對於非常短或非常長的資料列可能沒有用處。請注意,預設設定通常接近最佳設定,並且在某些情況下,設定此參數可能會產生負面影響。此參數不能為 TOAST table 設定。

parallel_workers (integer) #

這設定了應使用多少個 worker 來協助平行掃描此 table。如果未設定,系統將根據關聯大小決定一個值。規劃器或使用平行掃描的工具陳述式所選擇的實際 worker 數量可能會更少,例如由於 max_worker_processes 的設定。

autovacuum_enabled, toast.autovacuum_enabled (boolean) #

啟用或停用特定 table 的 autovacuum 精靈。如果為 true,autovacuum 精靈將按照第 24.1.6 節中討論的規則,對此 table 執行自動 VACUUM 和/或 ANALYZE 操作。如果為 false,則不會自動清理此 table,除非是為了防止交易 ID 包覆。有關防止包覆的更多資訊,請參閱第 24.1.5 節。請注意,如果 autovacuum 參數為 false,則 autovacuum 精靈根本不會執行(除非是為了防止交易 ID 包覆);設定個別 table 的儲存參數不會覆蓋該參數。因此,很少有意義明確地將此儲存參數設定為 true,只能設定為 false

vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) #

強制或停用在此 table 上執行 VACUUM 時的索引清理。預設值為 AUTO。使用 OFF 時,索引清理會停用;使用 ON 時,索引清理會啟用;使用 AUTO 時,每次執行 VACUUM 時都會動態做出決定。動態行為允許 VACUUM 避免不必要地掃描索引以移除非常少的無效元組。強制停用所有索引清理可以顯著加速 VACUUM,但也可能導致如果 table 修改頻繁,索引會嚴重膨脹。如果指定了VACUUMINDEX_CLEANUP 參數,則會覆蓋此選項的值。

vacuum_truncate, toast.vacuum_truncate (boolean) #

啟用或停用 vacuum 以嘗試截斷此 table 末端的任何空白頁面。預設值為 true。如果為 true,則 VACUUM 和 autovacuum 會執行截斷,並且截斷頁面的磁碟空間會返回給作業系統。請注意,截斷需要 table 上的 ACCESS EXCLUSIVE 鎖定。如果指定了VACUUMTRUNCATE 參數,則會覆蓋此選項的值。

autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) #

autovacuum_vacuum_threshold 參數的 table 預設值。

autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) #

autovacuum_vacuum_scale_factor 參數的 table 預設值。

autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) #

autovacuum_vacuum_insert_threshold 參數的 table 預設值。可以使用 -1 的特殊值來停用 table 上的插入 vacuum。

autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) #

autovacuum_vacuum_insert_scale_factor 參數的 table 預設值。

autovacuum_analyze_threshold (integer) #

autovacuum_analyze_threshold 參數的 table 預設值。

autovacuum_analyze_scale_factor (floating point) #

autovacuum_analyze_scale_factor 參數的 table 預設值。

autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) #

autovacuum_vacuum_cost_delay 參數的 table 預設值。

autovacuum_vacuum_cost_limittoast.autovacuum_vacuum_cost_limitinteger #

autovacuum_vacuum_cost_limit 參數的每個資料表值。

autovacuum_freeze_min_agetoast.autovacuum_freeze_min_ageinteger #

vacuum_freeze_min_age 參數的每個資料表值。請注意,如果每個資料表的 autovacuum_freeze_min_age 參數大於系統範圍的 autovacuum_freeze_max_age 設定的一半,自動清理程序將會忽略該參數。

autovacuum_freeze_max_agetoast.autovacuum_freeze_max_ageinteger #

autovacuum_freeze_max_age 參數的每個資料表值。請注意,如果每個資料表的 autovacuum_freeze_max_age 參數大於系統範圍的設定(只能設定較小的值),自動清理程序將會忽略該參數。

autovacuum_freeze_table_agetoast.autovacuum_freeze_table_ageinteger #

vacuum_freeze_table_age 參數的每個資料表值。

autovacuum_multixact_freeze_min_agetoast.autovacuum_multixact_freeze_min_ageinteger #

vacuum_multixact_freeze_min_age 參數的每個資料表值。請注意,如果每個資料表的 autovacuum_multixact_freeze_min_age 參數大於系統範圍的 autovacuum_multixact_freeze_max_age 設定的一半,自動清理程序將會忽略該參數。

autovacuum_multixact_freeze_max_agetoast.autovacuum_multixact_freeze_max_ageinteger #

autovacuum_multixact_freeze_max_age 參數的每個資料表值。請注意,如果每個資料表的 autovacuum_multixact_freeze_max_age 參數大於系統範圍的設定(只能設定較小的值),自動清理程序將會忽略該參數。

autovacuum_multixact_freeze_table_agetoast.autovacuum_multixact_freeze_table_ageinteger #

vacuum_multixact_freeze_table_age 參數的每個資料表值。

log_autovacuum_min_durationtoast.log_autovacuum_min_durationinteger #

log_autovacuum_min_duration 參數的每個資料表值。

user_catalog_tableboolean #

將資料表宣告為用於邏輯複寫的其他目錄資料表。有關詳細訊息,請參閱第 47.6.2 節。此參數不能為 TOAST 資料表設定。

注意事項

PostgreSQL 會自動為每個唯一約束和主鍵約束建立索引,以強制執行唯一性。因此,不需要為主鍵欄位明確建立索引。(有關更多資訊,請參閱 CREATE INDEX。)

在目前的實作中,不會繼承唯一約束和主鍵。這使得繼承和唯一約束的組合相當不實用。

一個資料表不能超過 1600 個欄位。(實際上,由於元組長度的限制,有效限制通常較低。)

範例

建立資料表 films 和資料表 distributors

CREATE TABLE films (
    code        char(5) CONSTRAINT firstkey PRIMARY KEY,
    title       varchar(40) NOT NULL,
    did         integer NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute
);

CREATE TABLE distributors (
     did    integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
     name   varchar(40) NOT NULL CHECK (name <> '')
);

建立具有二維陣列的資料表

CREATE TABLE array_int (
    vector  int[][]
);

為資料表 films 定義唯一資料表約束。唯一資料表約束可以在資料表的一個或多個欄位上定義

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT production UNIQUE(date_prod)
);

定義檢查欄位約束

CREATE TABLE distributors (
    did     integer CHECK (did > 100),
    name    varchar(40)
);

定義檢查資料表約束

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    CONSTRAINT con1 CHECK (did > 100 AND name <> '')
);

為資料表 films 定義主鍵資料表約束

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT code_title PRIMARY KEY(code,title)
);

為資料表 distributors 定義主鍵約束。以下兩個範例是等效的,第一個使用資料表約束語法,第二個使用欄位約束語法

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    PRIMARY KEY(did)
);

CREATE TABLE distributors (
    did     integer PRIMARY KEY,
    name    varchar(40)
);

為欄位 name 指派文字常數預設值,安排欄位 did 的預設值,透過選擇序列物件的下一個值來產生,並使 modtime 的預設值為插入列的時間

CREATE TABLE distributors (
    name      varchar(40) DEFAULT 'Luso Films',
    did       integer DEFAULT nextval('distributors_serial'),
    modtime   timestamp DEFAULT current_timestamp
);

在資料表 distributors 上定義兩個 NOT NULL 欄位約束,其中一個被明確地給定一個名稱

CREATE TABLE distributors (
    did     integer CONSTRAINT no_null NOT NULL,
    name    varchar(40) NOT NULL
);

name 欄位定義唯一約束

CREATE TABLE distributors (
    did     integer,
    name    varchar(40) UNIQUE
);

相同,指定為資料表約束

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name)
);

建立相同的資料表,為資料表及其唯一索引指定 70% 的填充因子

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name) WITH (fillfactor=70)
)
WITH (fillfactor=70);

建立資料表 circles,其中包含一個排除約束,可防止任何兩個圓形重疊

CREATE TABLE circles (
    c circle,
    EXCLUDE USING gist (c WITH &&)
);

在資料表空間 diskvol1 中建立資料表 cinemas

CREATE TABLE cinemas (
        id serial,
        name text,
        location text
) TABLESPACE diskvol1;

建立複合型別和型別化的資料表

CREATE TYPE employee_type AS (name text, salary numeric);

CREATE TABLE employees OF employee_type (
    PRIMARY KEY (name),
    salary WITH OPTIONS DEFAULT 1000
);

建立範圍分割的資料表

CREATE TABLE measurement (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (logdate);

建立範圍分割的資料表,其中分割鍵包含多個欄位

CREATE TABLE measurement_year_month (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));

建立清單分割的資料表

CREATE TABLE cities (
    city_id      bigserial not null,
    name         text not null,
    population   bigint
) PARTITION BY LIST (left(lower(name), 1));

建立雜湊分割的資料表

CREATE TABLE orders (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id);

建立範圍分割資料表的分割區

CREATE TABLE measurement_y2016m07
    PARTITION OF measurement (
    unitsales DEFAULT 0
) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');

建立範圍分割資料表的幾個分割區,其中分割鍵包含多個欄位

CREATE TABLE measurement_ym_older
    PARTITION OF measurement_year_month
    FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);

CREATE TABLE measurement_ym_y2016m11
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 11) TO (2016, 12);

CREATE TABLE measurement_ym_y2016m12
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 12) TO (2017, 01);

CREATE TABLE measurement_ym_y2017m01
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2017, 01) TO (2017, 02);

建立清單分割資料表的分割區

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b');

建立清單分割資料表的分割區,該資料表本身被進一步分割,然後向其新增一個分割區

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);

CREATE TABLE cities_ab_10000_to_100000
    PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);

建立雜湊分割資料表的分割區

CREATE TABLE orders_p1 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_p2 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_p3 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_p4 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 3);

建立預設分割區

CREATE TABLE cities_partdef
    PARTITION OF cities DEFAULT;

相容性

CREATE TABLE 命令符合SQL標準,但以下列出的例外情況除外。

暫存資料表

雖然 CREATE TEMPORARY TABLE 的語法與 SQL 標準相似,但效果並不相同。在標準中,暫存資料表只需定義一次,並自動存在於每個需要它們的會話中(從空的內容開始)。而 PostgreSQL 則要求每個會話針對要使用的每個暫存資料表發出自己的 CREATE TEMPORARY TABLE 指令。這允許不同的會話將相同的暫存資料表名稱用於不同的目的,而標準的方法會限制給定暫存資料表名稱的所有實例都具有相同的資料表結構。

標準對於暫存資料表行為的定義被廣泛忽略。PostgreSQL 在這方面的行為與其他幾個 SQL 資料庫相似。

SQL 標準還區分了全域和本機暫存資料表,其中本機暫存資料表在每個會話中的每個 SQL 模組中都有一組單獨的內容,但其定義仍然在會話之間共享。由於 PostgreSQL 不支援 SQL 模組,因此這種區別在 PostgreSQL 中並不重要。

為了相容性,PostgreSQL 將接受暫存資料表宣告中的 GLOBALLOCAL 關鍵字,但它們目前沒有任何作用。不建議使用這些關鍵字,因為未來版本的 PostgreSQL 可能會採用更符合標準的解釋。

暫存資料表的 ON COMMIT 子句也與 SQL 標準相似,但存在一些差異。如果省略了 ON COMMIT 子句,SQL 規定預設行為是 ON COMMIT DELETE ROWS。但是,PostgreSQL 中的預設行為是 ON COMMIT PRESERVE ROWSON COMMIT DROP 選項在 SQL 中不存在。

非延遲唯一性約束

UNIQUEPRIMARY KEY 約束不可延遲時,PostgreSQL 會在每次插入或修改列時立即檢查唯一性。SQL 標準規定唯一性應該僅在語句結束時強制執行;例如,當單個指令更新多個鍵值時,這會產生差異。要獲得符合標準的行為,請將約束宣告為 DEFERRABLE 但不延遲(即,INITIALLY IMMEDIATE)。請注意,這可能比立即唯一性檢查慢得多。

欄位檢查約束

SQL 標準規定 CHECK 欄位約束只能參考它們所應用於的欄位;只有 CHECK 資料表約束才能參考多個欄位。PostgreSQL 不強制執行此限制;它將欄位和資料表檢查約束同等對待。

EXCLUDE 約束

EXCLUDE 約束類型是 PostgreSQL 擴展。

外鍵約束

在外部鍵動作 SET DEFAULTSET NULL 中指定欄位列表的能力是 PostgreSQL 擴展。

外鍵約束可以引用唯一索引的欄位,而不是主鍵或唯一約束的欄位,這是 PostgreSQL 擴展。

NULL 約束

NULL 約束(實際上是非約束)是 PostgreSQL 對 SQL 標準的擴展,包含它是為了與某些其他資料庫系統相容(並且與 NOT NULL 約束對稱)。由於它是任何欄位的預設值,因此它的存在只是噪音。

約束命名

SQL 標準規定資料表和網域約束必須具有在包含資料表或網域的綱要中唯一的名稱。PostgreSQL 較為寬鬆:它僅要求約束名稱在附加到特定資料表或網域的約束中是唯一的。但是,基於索引的約束(UNIQUEPRIMARY KEYEXCLUDE 約束)不存在這種額外的自由,因為相關的索引與約束同名,並且索引名稱在同一綱要中的所有關係中必須是唯一的。

目前,PostgreSQL 根本不記錄 not-null 約束的名稱,因此它們不受唯一性限制。這可能會在未來的版本中更改。

繼承

透過 INHERITS 子句的多重繼承是 PostgreSQL 語言擴展。SQL:1999 及更高版本定義了使用不同語法和不同語義的單一繼承。PostgreSQL 尚未支援 SQL:1999 樣式的繼承。

零欄位資料表

PostgreSQL 允許建立沒有欄位的資料表(例如,CREATE TABLE foo();)。這是 SQL 標準的擴展,SQL 標準不允許零欄位資料表。零欄位資料表本身不是很有用,但是不允許它們會為 ALTER TABLE DROP COLUMN 建立奇怪的特殊情況,因此忽略此規範限制似乎更清晰。

多個 Identity 欄位

PostgreSQL 允許一個資料表有多個 identity 欄位。標準規定一個資料表最多可以有一個 identity 欄位。放寬這一限制主要是為了在進行綱要變更或遷移時提供更大的彈性。請注意,INSERT 指令僅支援一個適用於整個語句的覆寫子句,因此不太支援具有不同行為的多個 identity 欄位。

產生式欄位

STORED 選項不是標準的,但也由其他 SQL 實作使用。SQL 標準未指定產生式欄位的儲存。

LIKE 子句

雖然 SQL 標準中存在 LIKE 子句,但 PostgreSQL 接受的許多選項不在標準中,而標準中的某些選項未由 PostgreSQL 實作。

WITH 子句

WITH 子句是 PostgreSQL 擴展;儲存參數不在標準中。

表格空間

PostgreSQL 的表格空間概念不是標準的一部分。因此,TABLESPACEUSING INDEX TABLESPACE 子句是擴展。

類型化資料表

類型化資料表實作了 SQL 標準的一個子集。根據標準,類型化資料表具有與基礎複合類型對應的欄位,以及另一個作為 自我參照欄位 的欄位。PostgreSQL 不顯式支援自我參照欄位。

PARTITION BY 子句

PARTITION BY 子句是 PostgreSQL 擴展。

PARTITION OF 子句

PARTITION OF 子句是 PostgreSQL 擴展。

提交更正

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