ORACLE sequence各引數及建立修改刪除使用詳解示例
ORACLE沒有自增資料型別,如需生成業務無關的主鍵列或惟一約束列,可以用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 }
];
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以指示該序列不能在達到其最大值或最小值後產生更多的值。這是預設的。達到最大值會報錯:ORA-08004: sequence TEST_SEQ.NEXTVAL exceeds MAXVALUE and cannot be instantiated
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:這是預設的。
使用sequence時對系統效能大致有以下影響: -->Seq$基表
詳見: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小上百倍。
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; 其它引數不寫,使用系統預設哈哈
#####################################################
{ 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;
############################
序列常見使用場景:
可以在SELECT 語句,CREATE TABLE ... AS SELECT語句, CREATE MATERIALIZED VIEW ... AS SELECT中使用。
在UPDATE的SET中,在INSERT 的子句或VALUES中。序列可以由多個使用者同時訪問而不產生等待或鎖定。
第一次查詢要用 NEXTVAL,返回序列的初始值。
查詢當前序列號用:CURRVAL,返回的是最後一次引用NEXTVAL返回的值。
查詢下一個序列號用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;
CURRVAL
----------
14
SQL> select case when 1=2 then test1_seq.nextval
2 else null end seqvalue,test1_seq.currval from dual;
SEQVALUE CURRVAL
---------- ----------
15
SQL> select test1_seq.currval from dual;
CURRVAL
----------
15
SQL> select case
2 when 1=1 then test1_seq.nextval
3 end testseq,test1_seq.currval from dual;
TESTSEQ CURRVAL
---------- ----------
20 20
SQL> select case
2 when 1=2 then test1_seq.nextval
3 end testseq,test1_seq.currval from dual;
TESTSEQ CURRVAL
---------- ----------
21
參考:http://stackoverflow.com/questions/7810108/sequence-and-case-in-a-select-in-oracle
CREATE SEQUENCE語句及引數介紹:
詳見官方文件:http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_6015.htm#SQLRF01314建立序列:需要有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以指示該序列不能在達到其最大值或最小值後產生更多的值。這是預設的。達到最大值會報錯:ORA-08004: sequence TEST_SEQ.NEXTVAL exceeds MAXVALUE and cannot be instantiated
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:這是預設的。
使用sequence時對系統效能大致有以下影響: -->Seq$基表
詳見:http://blog.itpub.net/17203031/viewspace-7170421.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)
RAC時,如果序列號不要求有序建議用NOORDER+CACHE
ORACLE sequence建立示例:
create sequence bys.test_seqincrement 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序列常見使用場景:
可以在SELECT 語句,CREATE TABLE ... AS SELECT語句, CREATE MATERIALIZED VIEW ... AS SELECT中使用。
在UPDATE的SET中,在INSERT 的子句或VALUES中。序列可以由多個使用者同時訪問而不產生等待或鎖定。
第一次查詢要用 NEXTVAL,返回序列的初始值。
查詢當前序列號用:CURRVAL,返回的是最後一次引用NEXTVAL返回的值。
查詢下一個序列號用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;
---------------case when子句中使用SEQ時,
The statements in a WHEN clause can modify the database and call non-deterministic functions. There is no fall-through mechanism as in the C switch statement
Notice it doesn't say the statements in the "true" WHEN clause. So even if the when statement is false, the nextval will fire:
select
case when 1=0 then 'next ' || seq_id.nextval
when 1=1 then 'curr ' || seq_id.currval
end col1
from dual;
示例如下:--即WHEN中條件為FALSE時也會觸發執行序列的
NEXTVAL,但是CASE WHEN子句不返回值。
SQL> select test1_seq.currval from dual; CURRVAL
----------
14
SQL> select case when 1=2 then test1_seq.nextval
2 else null end seqvalue,test1_seq.currval from dual;
SEQVALUE CURRVAL
---------- ----------
15
SQL> select test1_seq.currval from dual;
CURRVAL
----------
15
SQL> select case
2 when 1=1 then test1_seq.nextval
3 end testseq,test1_seq.currval from dual;
TESTSEQ CURRVAL
---------- ----------
20 20
SQL> select case
2 when 1=2 then test1_seq.nextval
3 end testseq,test1_seq.currval from dual;
TESTSEQ CURRVAL
---------- ----------
21
參考:http://stackoverflow.com/questions/7810108/sequence-and-case-in-a-select-in-oracle
http://www.itpub.net/thread-1878625-1-1.html
相關文章
- curl常用引數詳解及示例
- 詳解Oracle建立表的引數Oracle
- Oracle序列使用:建立、刪除Oracle
- ORACLE表空間的建立修改刪除Oracle
- Oracle使用者的新增、修改、刪除及授權Oracle
- ntpq –p 各引數詳解
- Oracle 12c 手工建立 和 刪除 PDB 示例Oracle
- Oracle引數檔案 各引數解釋Oracle
- SQL Server觸發器建立、刪除、修改、檢視示例步驟SQLServer觸發器
- mysql使用者建立、修改、刪除及授權操作的總結MySql
- Oracle Sequence Cache 引數說明Oracle
- [FFmpeg]ffmpeg各類引數說明與使用示例
- [MYSQL][1]建立,修改,刪除表MySql
- 使用者建立授權及刪除
- Linux 建立修改刪除使用者和組Linux
- caffe網路各層引數詳解
- Oracle UNDO引數詳解Oracle
- Oracle使用者的建立和刪除Oracle
- Oracle 增加 修改 刪除 列Oracle
- oracle主鍵序列的建立,刪除,修改序列起始值Oracle
- redis配置檔案中各引數詳解Redis
- 42.QT-QSqlQuery類操作SQLite資料庫(建立、查詢、刪除、修改)詳解QTSQLite資料庫
- oracle建立/刪除表空間、建立/刪除使用者並賦予許可權Oracle
- oracle rac 核心引數詳解Oracle
- oracle RMAN引數配置詳解Oracle
- ORACLE DG之引數詳解Oracle
- Oracle 增加修改刪除欄位Oracle
- oracle修改表增加列刪除列修改列Oracle
- oracle job的建立和刪除Oracle
- Oracle GoldenGate常用引數詳解OracleGo
- 轉:oracle EXP /IMP引數詳解Oracle
- ORACLE filesystemio_options引數詳解及IO場景測試Oracle
- Oracle各種版本下“示例資料庫的建立”的建立Oracle資料庫
- Oracle引數修改小結Oracle
- sequence可能引發的各種lock/enqueueENQ
- sed 命令詳解及示例
- jquery datatables各引數詳細說明及簡單應用jQuery
- 從原始碼分析 Redis 非同步刪除各個引數的具體作用原始碼Redis非同步