CREATE SEQUENCE — 定義一個新的序列生成器
CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ]name
[ ASdata_type
] [ INCREMENT [ BY ]increment
] [ MINVALUEminvalue
| NO MINVALUE ] [ MAXVALUEmaxvalue
| NO MAXVALUE ] [ [ NO ] CYCLE ] [ START [ WITH ]start
] [ CACHEcache
] [ OWNED BY {table_name
.column_name
| NONE } ]
CREATE SEQUENCE
建立一個新的序列號生成器。這包括建立一個名為 name
的特殊單行表並進行初始化。生成器將由發出命令的使用者擁有。
如果給出了模式名,則序列將在指定的模式中建立。否則,它將在當前模式中建立。臨時序列存在於一個特殊的模式中,因此在建立臨時序列時不能指定模式名。序列名在同一模式中必須與任何其他關係(表、序列、索引、檢視、物化檢視或外部表)的名稱不同。
建立序列後,您可以使用函式 nextval
、currval
和 setval
來操作序列。這些函式在 第 9.17 節 中有說明。
雖然您不能直接更新序列,但您可以使用類似以下的查詢
SELECT * FROM name
;
來檢查序列的引數和當前狀態。特別是,序列的 last_value
欄位顯示了由任何會話分配的最後一個值。(當然,如果其他會話正在主動執行 nextval
呼叫,則此值可能在列印時已過時。)
TEMPORARY
或 TEMP
如果指定,序列物件僅為當前會話建立,並在會話退出時自動刪除。與臨時序列同名的現有永久序列(在此會話中)不可見,除非使用模式限定名引用它們。
UNLOGGED
如果指定,序列將作為未記錄序列建立。未記錄序列的更改不會寫入預寫日誌(WAL)。它們不是崩潰安全的:在崩潰或非正常關閉後,未記錄序列會自動重置為其初始狀態。未記錄序列也不會複製到備用伺服器。
與未記錄表不同,未記錄序列並未提供顯著的效能優勢。此選項主要用於透過標識列或序列列與未記錄表相關聯的序列。在這些情況下,讓序列 WAL 記錄和複製,但其關聯表不這樣做,通常是沒有意義的。
IF NOT EXISTS
如果同名關係已存在,則不引發錯誤。在這種情況下,會發出通知。請注意,不能保證現有關係與可能已建立的序列有任何相似之處 — 它甚至可能不是一個序列。
name
要建立的序列的名稱(可選擇模式限定)。
data_type
可選子句 AS
指定序列的資料型別。有效型別為 data_type
smallint
、integer
和 bigint
。bigint
是預設值。資料型別決定了序列的預設最小值和最大值。
增量
可選子句 INCREMENT BY
指定將哪個值新增到當前序列值以建立新值。正值將建立遞增序列,負值將建立遞減序列。預設值為 1。increment
minvalue
NO MINVALUE
可選子句 MINVALUE
確定序列可以生成的最小值。如果未提供此子句或指定了 minvalue
NO MINVALUE
,則將使用預設值。遞增序列的預設值為 1。遞減序列的預設值為資料型別的最小值。
maxvalue
NO MAXVALUE
可選子句 MAXVALUE
確定序列的最大值。如果未提供此子句或指定了 maxvalue
NO MAXVALUE
,則將使用預設值。遞增序列的預設值為資料型別的最大值。遞減序列的預設值為 -1。
CYCLE
NO CYCLE
CYCLE
選項允許序列在遞增序列達到 maxvalue
或遞減序列達到 minvalue
時迴繞。如果達到限制,下一個生成的數字將分別是 minvalue
或 maxvalue
。
如果指定了 NO CYCLE
,則在序列達到其最大值後,任何對 nextval
的呼叫都將返回錯誤。如果未指定 CYCLE
或 NO CYCLE
,則 NO CYCLE
是預設值。
start
可選子句 START WITH
允許序列從任意位置開始。遞增序列的預設起始值為 start
minvalue
,遞減序列的預設起始值為 maxvalue
。
cache
可選子句 CACHE
指定有多少序列號將被預分配並存儲在記憶體中以便更快訪問。最小值是 1(一次只能生成一個值,即沒有快取),這也是預設值。cache
OWNED BY
table_name
.column_name
OWNED BY NONE
OWNED BY
選項使序列與特定的表列關聯,這樣,如果該列(或其整個表)被刪除,序列也將被自動刪除。指定的表必須與序列擁有者相同,並且在同一模式下。 OWNED BY NONE
是預設值,表示沒有這種關聯。
使用 DROP SEQUENCE
刪除序列。
序列基於 bigint
算術,因此範圍不能超過 8 位元組整數的範圍(-9223372036854775808 到 9223372036854775807)。
由於 nextval
和 setval
呼叫從不回滾,因此如果需要“無間隙”分配序列號,則不能使用序列物件。可以透過獨佔鎖定一個包含計數器的表來構建無間隙分配;但這比序列物件昂貴得多,尤其是在許多事務需要併發訪問序列號的情況下。
如果用於將要由多個會話併發使用的序列物件的 cache
設定大於一,可能會獲得意外結果。每個會話將在一次訪問序列物件時分配和快取連續的序列值,並相應地增加序列物件的 last_value
。然後,該會話中 nextval
的下 cache
-1 次使用將僅返回預分配的值,而無需觸及序列物件。因此,任何在會話中分配但未使用過的數字將在該會話結束時丟失,從而在序列中產生“間隙”。
此外,雖然保證多個會話會分配不同的序列值,但在考慮所有會話時,這些值可能會亂序生成。例如,如果 cache
設定為 10,會話 A 可能會保留值 1..10 並返回 nextval
=1,然後會話 B 可能會保留值 11..20 並返回 nextval
=11,而此時會話 A 尚未生成 nextval
=2。因此,當 cache
設定為 1 時,可以安全地假設 nextval
值是按順序生成的;當 cache
設定大於 1 時,您只能假設 nextval
值是不同的,而不是它們是嚴格按順序生成的。另外,last_value
將反映任何會話保留的最新值,無論該值是否已由 nextval
返回。
另一個需要考慮的是,在這樣的序列上執行的 setval
不會被其他會話注意到,直到它們用完任何已快取的預分配值。
建立一個名為 serial
的遞增序列,從 101 開始
CREATE SEQUENCE serial START 101;
從此序列中選擇下一個數字
SELECT nextval('serial'); nextval --------- 101
從此序列中選擇下一個數字
SELECT nextval('serial'); nextval --------- 102
在 INSERT
命令中使用此序列
INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
在 COPY FROM
後更新序列值
BEGIN; COPY distributors FROM 'input_file'; SELECT setval('serial', max(id)) FROM distributors; END;
CREATE SEQUENCE
符合SQL標準,但有以下例外:
獲取下一個值是透過 nextval()
函式完成的,而不是使用標準的 NEXT VALUE FOR
表示式。
OWNED BY
子句是 PostgreSQL 的擴充套件。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。