oracle数据库主键自增序列_Oracle数据库序列详解
前言:
做過(guò)web開(kāi)發(fā)的人員基本上都知道,數(shù)據(jù)庫(kù)表中的主鍵值有的時(shí)候我們會(huì)用數(shù)字類型的并且自增。這樣mysql、sql server中的都可以使用工具創(chuàng)建表的時(shí)候很容易實(shí)現(xiàn)。但是oracle中沒(méi)有設(shè)置自增的方法,一般情況我們會(huì)使用序列和觸發(fā)器來(lái)實(shí)現(xiàn)主鍵自增的功能。下面這面文章主要介紹序列。
一、什么是序列
序列: Sequence 是oracle提供的用于產(chǎn)生一系列唯一數(shù)字的數(shù)據(jù)庫(kù)對(duì)象。由于oracle中沒(méi)有設(shè)置自增列的方法,所以我們?cè)趏racle數(shù)據(jù)庫(kù)中主要用序列來(lái)實(shí)現(xiàn)主鍵自增的功能。
二、怎么樣創(chuàng)建序列
三、如何使用序列
序列創(chuàng)建后,可以使用序列的NEXTVAL來(lái)獲取序列的下一個(gè)值,使用CURRVAL來(lái)查看當(dāng)前值。第一次使用必須先使用NEXTVAL來(lái)產(chǎn)生一個(gè)值后才可以使用CURRVAL進(jìn)行查看。
四、創(chuàng)建序列示例
4.1 最簡(jiǎn)單的序列示例
執(zhí)行這個(gè)創(chuàng)建語(yǔ)句會(huì)在數(shù)據(jù)庫(kù)中產(chǎn)生一個(gè)名字為seq_test的序列對(duì)象,其它的參數(shù)都會(huì)默認(rèn)使用默認(rèn)值。查看生成的源碼如下:
當(dāng)你調(diào)用seq_test這個(gè)序列時(shí),它會(huì)為你產(chǎn)生從1到999999999999999999999999999的連續(xù)遞增數(shù)值,從1開(kāi)始,每次增量為1,不循環(huán)產(chǎn)生。產(chǎn)生最大值后將無(wú)法使用。默認(rèn)使用緩存生成,每次緩存的數(shù)量為20個(gè)。關(guān)于緩存我們后面再講。
4.2 創(chuàng)建有最大值的非循環(huán)序列
這個(gè)序列雖然設(shè)置最小值為5,但由于開(kāi)始值為10,并且不循環(huán)產(chǎn)生,所以不會(huì)產(chǎn)生10以下的數(shù)值。需要注意的是,序列的起始值不能小于最小值,否則創(chuàng)建序列會(huì)報(bào)錯(cuò)。我們把上面代碼改成如下:
當(dāng)我們執(zhí)行序列提取到最大值300時(shí),序列會(huì)從最小值5開(kāi)始重新循環(huán)生成。而此序列第一次是從開(kāi)始值生成。
需要注意的是,如果我們創(chuàng)建一個(gè)循環(huán)序列,則必須要設(shè)定最大值,否則會(huì)報(bào)錯(cuò):
五、使用帶緩存的序列
創(chuàng)建序列時(shí)使用CACHE能提高性能,特別是在高并發(fā)的情況下對(duì)數(shù)據(jù)庫(kù)的性能提升還是不錯(cuò)的。但是使用緩存會(huì)有產(chǎn)生斷號(hào)的現(xiàn)象,如果你的業(yè)務(wù)要求序列產(chǎn)生的值必須是連續(xù)的,那就只能使用nocache了。
我們先來(lái)了解一下cache這個(gè)參數(shù)的作用。cache,它的用處是緩存指定個(gè)數(shù)的序列值。比如你設(shè)置的 cache 是20,那么在獲取 nextval 時(shí),Oracle 會(huì)直接從 cache 中取下一個(gè)序列值,如果 cache 中緩存的序列值沒(méi)有了(比如 cache 中的序列值用完了,或者被手工清空了),那么 Oracle 會(huì)再次產(chǎn)生20個(gè)序列值,并放置 cache 中供使用,這樣有助于提高序列值的獲取速度。
我們下面通過(guò)一個(gè)案例來(lái)演示一下緩存的作用:
此時(shí)執(zhí)行SEQ_CACHE.nextval 會(huì)返回產(chǎn)生第一個(gè)值1。調(diào)用SEQ_CACHE.currval 查看當(dāng)前值為1。
當(dāng)我們第一次調(diào)用nextval時(shí),由于設(shè)置了緩存數(shù)為20,序列會(huì)一次生成20個(gè)數(shù)值放在緩存里。當(dāng)我們?cè)俅握{(diào)用nextval時(shí)其實(shí)是從緩存里取到的值。假如我們此時(shí)將緩存清空再調(diào)用nextval,我們來(lái)測(cè)試一下。
發(fā)現(xiàn)獲取的值是21而不是2 。因?yàn)榫彺胬锏闹当磺蹇樟?所以系統(tǒng)會(huì)自動(dòng)又獲取20個(gè)新的連續(xù)值放在緩存里。
我們現(xiàn)在再執(zhí)行四次nextval,會(huì)得到當(dāng)前的值為25。此時(shí)我們?cè)俅吻蹇站彺?然后再次調(diào)用nextval來(lái)獲取序列。
我們會(huì)得到當(dāng)前的值為41。為什么呢?因?yàn)槊看蝟racle獲取20值是從上次獲取的最大值開(kāi)始的,而不是從當(dāng)前值開(kāi)始計(jì)算的!使用緩存會(huì)產(chǎn)生產(chǎn)生的數(shù)字不連接的風(fēng)險(xiǎn),如果系統(tǒng)出異常或oracle重啟則系統(tǒng)會(huì)清空緩存的數(shù)據(jù),當(dāng)調(diào)用nextval時(shí)會(huì)重新獲取相應(yīng)緩存設(shè)置的數(shù)量的值。
我們?cè)賮?lái)看一個(gè)帶緩存的案例:
為什么會(huì)出現(xiàn)這樣的錯(cuò)誤呢?
我們緩存設(shè)定的值是 50,而最大值是 300,那么為什么還會(huì)提示這樣的信息呢? 其實(shí)我們的 cache 雖然是 50,但是我們每次增長(zhǎng)值是 10。這樣 50 次緩存提取出的數(shù)是 500 (50*10),我們每次循環(huán)的最大值是300,所以就提示我們一次獲取的緩存值必須小于一次循環(huán)產(chǎn)生的最大值。
我們將代碼修改如下:
這又是為什么呢?我們一次循環(huán)的最大值已經(jīng)設(shè)置成500了,為什么還有這樣的錯(cuò)誤提示?這是因?yàn)檫€存在一個(gè) minvalue ,minvalue 和 maxvalue 之間是 490 個(gè)數(shù),也就是一次循環(huán)可以提取 490,但是我們的緩存是500。
我們將代碼修改如下:
發(fā)現(xiàn)創(chuàng)建序列成功。在創(chuàng)建序列的時(shí)候關(guān)于緩存值的設(shè)置我們有一個(gè)基本的公式要求:
最大值最小值緩存值每次循環(huán)的值
只要滿足這個(gè)公式的緩存值設(shè)置就沒(méi)有問(wèn)題。
總結(jié):
通過(guò)上述我們發(fā)現(xiàn)使用序列有幾個(gè)基本的約束條件,總結(jié)有以下幾條:
1、序列第一次必須先調(diào)用nextval獲取一個(gè)序列值才能使用currval查看當(dāng)前值
2、序列的起始值不能小于最小值
3、創(chuàng)建一個(gè)循環(huán)序列,則必須要設(shè)定最大值
4、如果創(chuàng)建帶緩存的序列,緩存的值必須滿足約束公式: 最大值-最小值>=(緩存值-1)*每次循環(huán)的值
以上是對(duì)oracle數(shù)據(jù)庫(kù)的序列的詳細(xì)介紹,希望能對(duì)大家理解和掌握序列的使用有所幫助。
總結(jié)
以上是生活随笔為你收集整理的oracle数据库主键自增序列_Oracle数据库序列详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Vue + Canvas 实现头像截图上
- 下一篇: 打算开源一个低代码平台,第二天,包含【工