Oracle SEQUENCE 具體說明
ORACLE沒有自增數據類型,如需生成業務無關的主鍵列或惟一約束列,能夠用sequence序列實現。
CREATE SEQUENCE語句及參數介紹:
創建序列:須要有CREATE SEQUENCE或者CREATE ANY SEQUENCE權限,
CREATE SEQUENCE [ schema. ]sequence
[ { INCREMENT BY | START WITH } integer
| { MAXVALUE integer | NOMAXVALUE }
| { MINVALUE integer | NOMINVALUE }
| { CYCLE | NOCYCLE }
| { CACHE integer | NOCACHE }
| { ORDER | NOORDER }
];
CREATE SEQUENCE各參數具體解釋:
schema指定在哪個用戶的schema下創建sequence。如不指定。默認在當前用戶下創建。
sequence指定要創建的sequence序列名
註意:假設僅僅指定以上參數,將啟動一個從1開始,以1為單位遞增,沒有最大值限制的遞增序列。
假設要創建一個沒有約束的序列,遞增序列時:忽略MAXVALUE參數或指定NOMAXVALUE;遞減序列:省略MINVALUE參數或指定NOMINVALUE。
假設要創建一個有限制的序列。遞增序列時:指定MAXVALUE參數;遞減序列:指定MINVALUE參數。
此時序列達到限制後會報錯:
假設要創建一個有限制的序列在達到限制後又一次啟動,指定MAXVALUE和MINVALUE後。還須要指定CYCLE。
假設不指定MINVALUE,默覺得NOMINVALUE,
這個值是1.
INCREMENT BY指定序列號間的間隔,這個整數值能夠是不論什麽正整數或負整數,但不能是0。
這個值最多有28位數字。
絕對值必須小於MAXVALUE與MINVALUE的差異(如非在此區間報錯:ORA-04005: INCREMENT must be less than MAXVALUE minus MINVALUE)。
假設這個值是負的,則該序列下降。假設該值為正。則序列上升。假設省略此子句。則間隔缺省為1。
START WITH指定要產生的第一個序列號。
此子句啟動一個遞增序列,要大於最小值;或啟動一個遞減序列,小於它最大值。
對於遞增序列,默認值是序列中的最小值。對於遞減的序列,默認值是序列中的最大值。這個整數值能夠最多28位數字。
這個值和達到限制的最大/最小值後又一次啟動時的值沒有關系(如遞增序列創建時指定有最大值最小值且指定CYCLE,則序列達到最大值後,
會從最小值開始;如未指定兼包最小值,默認1開始。
MaxValue指定序列可生成的最大值。這個整數值能夠最多28位數字。
MAXVALUE必須>=START WITH、必須大於MINVALUE。
NOMAXVALUE:指定NOMAXVALUE表示遞增序列的最大值是10的27次方,或遞減序列最大值為-1。
這是默認的。
MINVALUE:指定序列的最小值。
這個整數值能夠最多28位數字。MINVALUE必須<=START WITH的值和必須小於MAXVALUE。
如此處不符,報:ORA-04006: START WITH cannot be less than MINVALUE。不指定此參數時,默認是1.
NOMINVALUE:指定NOMINVALUE來表示遞增的序列最小值為1,遞減序列為負10的26次方。
這是默認的。
CYCLE:指定循環,表明序列在達到它的最大或最小值後生成的值。當遞增序列達到最大值後,再從最小值開始循環。
當遞減序列達到最小值。從最大值開始循環。
NOCYCLE:指定NOCYCLE以指示該序列不能在達到其最大值或最小值後產生很多其他的值。
這是默認的。
CACHE :指定數據庫為序列預分配多少個值放在內存中以便更快訪問。這個整數值能夠最多28位數字。該參數最小值為2;
這個值必須小於一個CYCLE循環的數(比方從1-100是一個循環。CACHE要小於100,不然可能 一次CACHE的值要有反復的會出錯。
報錯是:ORA-04013: number to CACHE must be less than one cycle)。
計算公式是:(CEIL (MAXVALUE - MINVALUE)) / ABS (INCREMENT)
假設系統故障,內存中未使用的CACHE值會丟失,將會導致序列不連續。
ORACLE建議在RAC中使用CACHE來提高性能。
NOCACHE :指定該序列值不被預分配。假設省略CACHE和NOCACHE,數據庫默認會緩存20個序列號。
ORDER :僅僅有在RAC時須要指定。指定ORDER 是為了保證序列號是由於有請求才生成的。
在使用序列號做為一個時間戳時非常實用。
NOORDER:這是默認的。
使用序列
序列生成的是一系列整數數字.一個序列中包括兩個"偽列" 。分別為"Currval"和"Nextval",能夠分別用來獲取該序列的當前值和下一個值.
盡管我們在定義時指定序列初始值為1但並沒有真正初始化該值. 當在檢索序列的當前值前,必須通過檢索序列的下一個值即Nextval來對序列進行
初始化操作.在選擇了Nextval時,該序列就被初始化為1.
使用sequence時對系統性能大致有下面影響:
詳見:http://blog.itpub.net/17203031/viewspace-717042
1.Seq$基表是記錄系統sequence的數據字典表.每次調用nextval,會遞歸調用更新並COMMIT Seq$基表。
2.更新Seq$基表並提交會產生redo log--幾百字節,COMMIT頻繁會造成LGWR的壓力;過多redo log生成。造成LGWR壓力、恢復時費時等。
3.多個會話使用sequence可能出現爭用,等待事件row lock contention
對於nocache/cache參數:
nocache:每次使用nextval,都會更新Seq$基表並COMMIT。
cache:僅僅有在內存中cache的序列號使用完後才會又一次獲取sequence。才會更新Seq$基表並提交。
比方cache設置為2000,則在使用sequence時對性能影響比nocache小上千倍。
所以普通情況下。建議設置一個較大的cache值,用於進行性能的優化。
(默認不指定nocache時是20)
#####################################################
ORACLE sequence創建演示樣例:
create sequence bys.test_seq
increment by 3
start with 5
maxvalue 18
minvalue 4
cycle
cache 4;
在bys用戶下創建名為test_seq的sequence
從5開始,每次添加3,最大值是18。最小值是4
同意重用,cache 4 表示會緩存四個序列號。比方5 8 11 14
當然在實驗中也能夠使用最簡單的:create sequence bys.test_seq2; 其他參數不寫,使用系統默認哈哈
#####################################################
ORACLE sequence改動和刪除演示樣例:
ALTER SEQUENCE [ schema. ]sequence
{ INCREMENT BY integer
| { MAXVALUE integer | NOMAXVALUE }
| { MINVALUE integer | NOMINVALUE }
| { CYCLE | NOCYCLE }
| { CACHE integer | NOCACHE }
| { ORDER | NOORDER }
}
改動時的三個註意事項:
假設要使序列start with不同的數字,僅僅能刪除序列重建。
假設在使用NEXTVAL初始化序列前改變INCREMENT BY的值,一些序列號會被跳過。
解決跳過問題的方法--刪除重建
改動的各個參數的新值依舊要滿足create sequence各參數介紹中的描寫敘述。
NEXTVAL初始化序列前改變INCREMENT BY的值演示樣例:
create sequence bys.seq3
increment by 3
start with 5
maxvalue 18
nominvalue
cycle
cache 4;
BYS@ bys3>alter sequence bys.seq3 increment by 5; --初始化前改動
Sequence altered.
BYS@ bys3>select seq3.nextval from dual; --初始化時確實跳過了一些數字。
。
NEXTVAL
----------
7
BYS@ bys3>select seq3.nextval from dual;
NEXTVAL
----------
12
演示樣例改動語句:
ALTER SEQUENCE customers_seq MAXVALUE 1500;
ALTER SEQUENCE customers_seq CYCLE CACHE 5;
刪除序列語句:
DROP SEQUENCE [ schema. ]sequence_name ;
如:BYS@ bys3>drop sequence bys.seq2;
############################
ORACLE sequence使用演示樣例
詳見官方文檔--http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns002.htm#i1006157
序列常見使用場景:
1能夠在SELECT 語句。CREATE TABLE ... AS SELECT語句。 CREATE MATERIALIZED VIEW ... AS SELECT中使用。
2在UPDATE的SET中,在INSERT 的子句或VALUES中。序列能夠由多個用戶同一時候訪問而不產生等待或鎖定。
3第一次查詢要用 NEXTVAL,返回序列的初始值。
4查詢當前序列號用:CURRVAL,返回的是最後一次引用NEXTVAL返回的值。
5查詢下一個序列號用NEXTVAL--用此命令時,sequence會先添加1或increment by指定的值,然後返回sequence值
本實驗中的查詢:
BYS@ bys3>select test_seq.currval from dual; ---未使用NEXTVAL初始化。故報此錯。
select test_seq.currval from dual
*
ERROR at line 1:
ORA-08002: sequence TEST_SEQ.CURRVAL is not yet defined in this session
BYS@ bys3>select test_seq.nextval from dual; 第一次使用NEXTVAL。顯示的是創建時start with指定的值
NEXTVAL
----------
5
BYS@ bys3>select test_seq.currval from dual; 使用currval查到當前序列號---最後一次引用NEXTVAL返回的值
CURRVAL
----------
5
BYS@ bys3>select test_seq.nextval from dual; --一直運行nextval。觀察序列達到maxvalue指定的值後怎樣循環使用
NEXTVAL
----------
17
BYS@ bys3>select test_seq.nextval from dual; --序列達到maxvalue指定的值後返回的是minvalue指定的值而不是start with了。如未指定minvalue或指定NOMINVALUE,則是返回1.
NEXTVAL
----------
4
BYS@ bys3>insert into test values(test_seq.nextval,‘seqtest‘); --使用INSERT語句調用序列
1 row created.
BYS@ bys3>select * from test;
OBJECT_NAME STATUS
------------ -------
10 seqtest
BYS@ bys3>insert into test values(test_seq.currval,‘seqtest‘);
1 row created.
BYS@ bys3>select * from test;
OBJECT_NAME STATUS
------------ -------
10 seqtest
10 seqtest
BYS@ bys3>insert into test(object_name) select test_seq.nextval from dual; --使用INSERT子語調用序列
1 row created.
BYS@ bys3>select * from test;
OBJECT_NAME STATUS
------------ -------
10 13
10 16
4
BYS@ bys3>update test set status=test_seq.nextval; --使用UPDATE語句調用序列
2 rows updated.
BYS@ bys3>select * from test;
OBJECT_NAME STATUS
------------ -------
10 13
10 16
BYS@ bys3>delete test where status=test_seq.currval; --DELETE中不能使用sequence做條件
delete test where status=test_seq.currval
*
ERROR at line 1:
ORA-02287: sequence number not allowed here
利用解發器自己主動為表插入遞增序列:---相似自增字段的作用
建解發器代碼為:
create or replace trigger tri_test_id
before insert on test --test 是表名
for each row
declare
nextid number;
begin
IF :new.testid IS NULL or :new.testid=0 THEN --DepartId是列名
select seq1.nextval --seq1是提前創建好的序列的名字
into nextid from sys.dual;
:new.testid:=nextid;
end if;
end tri_test_id;
Oracle SEQUENCE 具體說明