全部產品
Search
文件中心

PolarDB:CREATE SEQUENCE

更新時間:Jul 06, 2024

CREATE SEQUENCE用於建立一個新的序列數發生器。

簡介

CREATE SEQUENCE建立一個新的序列數發生器。這涉及到用名稱 name建立並且初始化一個新的特殊的單行表。該發生器將由發出該命令的使用者所擁有。

如果給出一個模式名稱,則該序列將被建立在指定的模式中。否則它會被建立在當前模式中。臨時序列存在於一個特殊的模式中,因此在建立臨時序列時不能給出模式名。序列名稱必須與同一模式中任何其他序列、表、索引、 視圖或者外部表格的名稱不同。

在序列被建立後,可以使用函數 nextvalcurrval以及 setval來操作該序列。

儘管無法直接更新一個序列,可以使用這樣的查詢:

    SELECT * FROM name;

來檢查一個序列的參數以及目前狀態。特別地,序列的 last_value域顯示被任意會話最後一次取得的值(當然, 在被列印時該值可能已經過時了,因為可能有其他會話正在執行 nextval調用)。

文法

    CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] name [ INCREMENT [ BY ] increment ]
        [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
        [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
        [ OWNED BY { table_name.column_name | NONE } ]

參數

TEMPORARY or TEMP如果被指定,只會為這個會話建立序列對象,並且在會話退出時自動刪除它。當臨時序列存在時,已有的同名永久序列(在這個會話中) 會變得不可見,不過可以用模式限定的名稱來引用同名永久序列。

IF NOT EXISTS如果已經存在一個同名的關係時不要拋出錯誤。這種情況下會發出一個提示。注意這不保證現有的關係與即將建立的序列相似 — 它甚至可能都不是一個序列。

name要建立的序列的名稱(可以是模式限定的)。

data_type可選的子句AS data_type 指定序列的資料類型。有效類型是 smallintinteger、 和bigint。預設是bigint。 資料類型決定了序列的預設最小和最大值。

increment可選的子句INCREMENT BY increment指定為了建立新值會把哪個值加到當前序列值上。一個正值將會創造一個上升序列,負值會創造一個下降序列。預設值是 1。

minvalueNO MINVALUE可選的子句MINVALUE minvalue決定一個序列能產生的最小值。如果沒有提供這個子句或者指定了 NO MINVALUE,那麼會使用預設值。 升序序列的預設值為 1。降序序列的預設值為資料類型的最小值。

maxvalueNO MAXVALUE可選的子句MAXVALUE maxvalue決定該序列的最大值。如果沒有提供這個子句或者指定了 NO MAXVALUE,那麼將會使用預設值。 升序序列的預設值是資料類型的最大值。降序序列的預設值是-1。

start可選的子句START WITH start 允許序列從任何地方開始。對於上升序列和下降序列來說,預設的開始值分別是 minvaluemaxvalue

cache可選的子句CACHE cache指定要預分配多少個序列數並且把它們放在記憶體中以便快速存取。最小值為 1 (一次只產生一個值,即沒有緩衝),預設值也是 1。

CYCLENO CYCLE對於上升序列和下降序列,CYCLE選項允許序列在分別達到 maxvalueminvalue時回卷。如果達到該限制,下一個產生的數字將分別是 minvaluemaxvalue

如果指定了NO CYCLE,當序列到達其最大值後任何nextval調用將返回一個錯誤。如果 CYCLENO CYCLE都沒有被指定,則預設為NO CYCLE

OWNED BY table_name. column_nameOWNED BY NONEOWNED BY選項導致序列被與一個特定的表列關聯在一起,這樣如果該列(或者整個表)被刪除,該序列也將被自動刪除。 指定的表必須和序列具有相同的擁有者並且在同一個模式中。預設選項 OWNED BY NONE指定該序列不與某個列關聯。

說明

使用DROP SEQUENCE移除一個序列。

序列是基於bigint演算法的,因此範圍是不能超過一個八位元組整數的範圍(-9223372036854775808 到 9223372036854775807)。

由於nextvalsetval調用絕不會復原, 如果需要序數的“無間隙”分配,則不能使用序列對象。可以通過在一個只包含一個計數器的表上使用獨佔鎖定來構建無間隙的分配, 但是這種方案比序列對象開銷更大,特別是當有很多事務並發請求序數時。

如果對一個將由多個會話並發使用的序列對象使用了大於 1 的 cache設定,可能會得到意想不到的結果。 每個會話會在訪問該序列對象時分配並且緩衝後續的序列值,並且相應地增加該序列對象的last_value。然後,在該會話中下一次 nextval會做 cache-1,並且簡單地返回預分配的值而不修改序列對象。因此,任何已指派但沒有在會話中使用的數字將會在該會話結束時丟失,導致該序列中的“空洞”。

進一步,儘管多個會話能分配到不同的序列值,這些值可能會在所有會話都被考慮時產生出來。例如, cache的設定為 10,會話 A 可能儲存值 1..10 並且返回nextval=1,然後會話 B 可能儲存值 11..20 並且在 A 產生nextval=2 之前返回 nextval=11。因此,如果 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;