1. 程式人生 > >Oracle序列號

Oracle序列號

序列號SEQUENCE:是Oracle提供的用於產生一系列唯一數字的資料庫物件。

序列號在資料庫中是一個共享物件, 序列號是一個計數器,它並不會與特定的表關聯。

主要用於提供主鍵值或唯一約束值。

將序列值裝入記憶體可以提高訪問效率。

建立序列號語法:

CREATE SEQUENCE [SCHEMA.]SEQUENCE_NAME

       [INCREMENT BY N]

       [START WITH N]

       [{MAXVALUE N | NOMAXVALUE}]

       [{MINVALUE N | NOMINVALUE}]

       [{CYCLE | NOCYCLE}]

       [{CACHE N | NOCACHE}];

SEQUENCE_NAME:序列號名稱

INCREMENT BY用於定義序列的步長,如果省略,則預設為1,如果出現負值,則代表Oracle序列的值是按照此步長遞減的。

START WITH 定義序列的初始值(即產生的第一個值),預設為1。

MAXVALUE 定義序列生成器能產生的最大值。選項NOMAXVALUE是預設選項,代表沒有最大值定義,這時對於遞增Oracle序列,系統能夠產生的最大值是10的27次方;對於遞減序列,最大值是-1。

MINVALUE定義序列生成器能產生的最小值。選項NOMAXVALUE是預設選項,代表沒有最小值定義,這時對於遞減序列,系統能夠產生的最小值是-10的26次方;對於遞增序列,最小值是1。

CYCLENOCYCLE 表示當序列生成器的值達到限制值後是否迴圈。CYCLE代表迴圈,NOCYCLE代表不迴圈。如果迴圈,則當遞增序列達到最大值時,迴圈到最小值;最小值為1。對於遞減序列達到最小值時,迴圈到最大值。如果不迴圈,達到限制值後,繼續產生新值就會發生錯誤。

CACHE(緩衝)定義存放序列的記憶體塊的大小,預設為20。NOCACHE表示不對序列進行記憶體緩衝。對序列進行記憶體緩衝,可以改善序列的效能。 快取選項會造成資料丟失,當例項異常關閉時。

如果指定CACHE值,ORACLE就可以預先在記憶體裡面放置一些SEQUENCE,這樣存取的快些。CACHE裡面的取完後,ORACLE自動再取一組到CACHE。使用CACHE或許會跳號, 比如資料庫突然不正常DOWN掉(SHUTDOWN ABORT),CACHE中的SEQUENCE就會丟失。舉個例子:比如你的SEQUENCE中CACHE 100,那當你SEQUENCE取到90時突然斷電,那麼在你重啟資料庫後,SEQUENCE的值將從101開始。

如果指定NOCACHE值,ORACLE就不會預先在記憶體裡面存放SEQUENCE,當然這也就可以避免資料庫不正常DOWN掉的SEQUENCE丟失。不過會產生一些問題:建立NOCACHE SEQUENCE在高併發訪問時,容易導致ROW CACHE LOCK等待事件,主要原因是每次獲取NEXTVAL時都需要修改ROWCACHE中的字典資訊。使用NOCACHE SEQUENCE,還會導致如下問題:

由於每次修改字典資訊都需要COMMIT,可能導致LOG FILE SYNC等待,NOCACHE SEQUENCE在RAC環境下,會對基於SEQUENCE生成的列建立的索引,造成例項間大量索引塊爭用,基於以上問題,避免建立NOCACHE SEQUENCE。

SEQUENCE相關保護機制:

ROW CACHE LOCK:在呼叫SEQUENCE.NEXTVAL情況下需要修改資料字典時發生,對應ROW CACHE LOCK事件。

SQ LOCK:在記憶體快取(並非ROW CACHE)上獲取SEQUENCE.NEXTVAL時發生,對應ENQ:SQ-CONTENTION事件。

SV LOCK:RAC環境下獲取CACHE+ORDER屬性的SEQUENCE.NEXTVAL時發生,對應DFS LOCK HANDLE事件。

使用序列號會產生跳號,序列在下列情況下出現裂縫:

回滾

系統異常

多個表同時使用同一序列

序列號使用:

-- 返回序列中下一個有效的值,任何使用者都可以引用

SELECT SEQUENCE_NAME.NEXTVAL FROM DUAL; 

-- 序列的當前值

SELECT SEQUENCE_NAME.CURRVAL FROM DUAL; 

例項應用:實現ID的自動遞增

建立序列號

CREATE SEQUENCE TEST_SEQ INCREMENT BY 1 START WITH 1 MAXVALUE 30000 MINVALUE 1

CACHE 2;

建立表

CREATE TABLE TEST_TABLE(

ID NUMBER(6),

NAME VARCHAR2(30),

CONSTRAINT PK_ID PRIMARY KEY(ID)

);

插入資料 

INSERT INTO TEST_TABLE VALUES(TEST_SEQ.NEXTVAL,'TOM');

COMMIT;

檢視資料庫中的序列號:

SELECT * FROM USER_SEQUENCES;

SELECT * FROM ALL_SEQUENCES;

SELECT * FROM DBA_SEQUENCES;

修改序列號:

ALTER SEQUENCE SEQUENCE_NAME

       [INCREMENT BY N]

       [{MAXVALUE N | NOMAXVALUE}]

       [{MINVALUE N | NOMINVALUE}]

       [{CYCLE | NOCYCLE}]

       [{CACHE N | NOCACHE}];

不能修改序列的初始值,否則會報ORA-02283:無法更改啟動序列號

刪除序列號:

DROP SEQUENCE [SCHEMA.]序列名;