詳解Oracle數(shù)據(jù)庫(kù)主鍵SYS_GUID()
在oracle8i以后提供了一個(gè)生成不重復(fù)的數(shù)據(jù)的一個(gè)函數(shù)sys_guid()一共32位,生成的依據(jù)主要是時(shí)間和機(jī)器碼,具有世界唯一性,類(lèi)似于java中的UUID(都是世界唯一的)。
SYS_GUID
SYS_GUID同Oracle管理員所使用的傳統(tǒng)的序列(sequence)相比具有諸多優(yōu)勢(shì)。一個(gè)序列生成器只是簡(jiǎn)單地創(chuàng)建從給定的起點(diǎn)開(kāi)始的一系列整數(shù)值,而且它被用在選擇陳述式的時(shí)候自動(dòng)地遞增該系列。
序列生成器所生成的數(shù)字只能保證在單個(gè)實(shí)例里是唯一的,這就不適合將它用作并行或者遠(yuǎn)程環(huán)境里的主關(guān)鍵字,因?yàn)楦髯原h(huán)境里的序列可能會(huì)生成相同的數(shù)字,從而導(dǎo)致沖突的發(fā)生。SYS_GUID會(huì)保證它創(chuàng)建的標(biāo)識(shí)符在每個(gè)數(shù)據(jù)庫(kù) 里都是唯一的。
此外,序列必須是DML陳述式的一部分,因此它需要一個(gè)到數(shù)據(jù)庫(kù)的往返過(guò)程(否則它就不能保證其值是唯一的)。SYS_GUID源自不需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn)的時(shí)間戳和機(jī)器標(biāo)識(shí)符,這就節(jié)省了查詢(xún)的消耗。
使用
SYS_GUID() 生成32位的唯一編碼。來(lái)生成唯一主鍵
例如:
- create table test
- (
- id raw(16) default sys_guid() primary key,
- name varchar2(100)
- );
- insert into test values(sys_guid(),'t1');
這樣就能生成唯一的主鍵id了,插入數(shù)據(jù)時(shí)不用插入id列。
SYS_GUID作為一個(gè)主關(guān)鍵字?
- create table use_seq_table(id integer );
- create sequence use_seq_sequence;
- insert into use_seq_table values (use_seq_sequence_value.nextval );
- create table use_guid_table(id raw (16));
- insert into use_guid_table(sys_guid());
很多應(yīng)用程序都依靠序列生成器來(lái)創(chuàng)建數(shù)據(jù)行的主關(guān)鍵字,這些數(shù)據(jù)行沒(méi)有一個(gè)明顯的主值,這也就是說(shuō),在這樣的數(shù)據(jù)集里一條記錄的創(chuàng)建就會(huì)讓數(shù)據(jù)列發(fā)生改變。因此,管理員可能會(huì)對(duì)在表格中將SYS_GUID用作主關(guān)鍵字而不使用序列數(shù)感興趣。這在對(duì)象在不同機(jī)器的不同數(shù)據(jù)庫(kù)里生成以及需要在后來(lái)合并到一起的情況下很有用。
但是,SYS_GUID所生成的值是一個(gè)16位的原始值。序列所生成的整數(shù)不會(huì)使用16位(的值),除非它達(dá)到了10的30次方(每個(gè)字節(jié)有兩位),而且數(shù)字是相當(dāng)獨(dú)特的:
- SQL> select dump (123456789012345678901234567890) from dual ;
較短的值就意味著用于表格和索引的存儲(chǔ)空間更少,以及查詢(xún)?cè)L問(wèn)的時(shí)間更短。
使用SYS_GUID或者序列會(huì)在數(shù)據(jù)庫(kù)使用周期里的某些地方造成性能上的消耗,對(duì)于SYS_GUID而言,性能上的影響在查詢(xún)時(shí)間和 創(chuàng)建時(shí)間上(在表格里要?jiǎng)?chuàng)建更多的塊和索引以容納數(shù)據(jù))。對(duì)序列而言,性能上的影響在查詢(xún)期間,在這個(gè)時(shí)候,SGA序列的緩沖區(qū)被用光。在缺省情況下,一 個(gè)序列一次會(huì)緩沖20個(gè)值。如果數(shù)據(jù)庫(kù)沒(méi)有使用這些值就關(guān)閉了,它們就會(huì)被丟失。
SYS_GUID生成的值的另一個(gè)顯著的不足之處是,管理這些值會(huì)變得困難得多。你必須(手動(dòng))輸入它們或者通過(guò)腳本來(lái)填充它們,或者將它們作為Web參數(shù)來(lái)傳遞。
出于這些原因,將SYS_GUID作為一個(gè)主關(guān)鍵字不是一個(gè)很好主意,除非是在一個(gè)并行的環(huán)境里或者希望避免使用管理序列生成器的情況下。
總結(jié)
相比于JAVA的uuid,SYS_GUID優(yōu)點(diǎn)就是生成的字符串是唯一的,但其和UUID有同樣的弊端:生成的序列過(guò)長(zhǎng)并且沒(méi)有規(guī)律不方便記憶。SYS_GUID的應(yīng)用場(chǎng)景是在于:當(dāng)數(shù)據(jù)庫(kù)某字段設(shè)置為唯一,則可用次生成(比如主鍵)。