CREATE SEQUENCE — 定義一個新的序列生成器
CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name
[ AS data_type ]
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ [ NO ] CYCLE ]
[ START [ WITH ] start ]
[ CACHE cache ]
[ 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_typesmallint、integer 和 bigint。bigint 是預設值。資料型別決定了序列的預設最小值和最大值。
增量可選子句 INCREMENT BY 指定將哪個值新增到當前序列值以建立新值。正值將建立遞增序列,負值將建立遞減序列。預設值為 1。increment
minvalueNO MINVALUE可選子句 MINVALUE 確定序列可以生成的最小值。如果未提供此子句或指定了 minvalueNO MINVALUE,則將使用預設值。遞增序列的預設值為 1。遞減序列的預設值為資料型別的最小值。
maxvalueNO MAXVALUE可選子句 MAXVALUE 確定序列的最大值。如果未提供此子句或指定了 maxvalueNO MAXVALUE,則將使用預設值。遞增序列的預設值為資料型別的最大值。遞減序列的預設值為 -1。
CYCLENO CYCLECYCLE 選項允許序列在遞增序列達到 maxvalue 或遞減序列達到 minvalue 時迴繞。如果達到限制,下一個生成的數字將分別是 minvalue 或 maxvalue。
如果指定了 NO CYCLE,則在序列達到其最大值後,任何對 nextval 的呼叫都將返回錯誤。如果未指定 CYCLE 或 NO CYCLE,則 NO CYCLE 是預設值。
start可選子句 START WITH 允許序列從任意位置開始。遞增序列的預設起始值為 startminvalue,遞減序列的預設起始值為 maxvalue。
cache可選子句 CACHE 指定有多少序列號將被預分配並存儲在記憶體中以便更快訪問。最小值是 1(一次只能生成一個值,即沒有快取),這也是預設值。cache
OWNED BY table_name.column_nameOWNED BY NONEOWNED 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 的擴充套件。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。