我們?cè)谑褂肧QlServer2012數(shù)據(jù)庫的時(shí)候,當(dāng)數(shù)據(jù)庫實(shí)例被重啟后,表里的IDENTITY類型的字段,實(shí)際的跳轉(zhuǎn)取決于該字段的類型,如果是INT類型,自動(dòng)跳轉(zhuǎn)為1000,如果是bigint,跳轉(zhuǎn)為10000,從我們程序開發(fā)的角度,這個(gè)是無法接受的,目前只是在SQLServer2012種出現(xiàn),其他版本的沒有出現(xiàn)。
就在幾天前,我們的一個(gè)工程師聲稱,我們一個(gè)IDENTITY列的值直接增加了10000,本來應(yīng)該是2200現(xiàn)在是12001,現(xiàn)在我們必須解決這個(gè)問題。
按照道理,每次跳轉(zhuǎn)的值不應(yīng)該改變,于是開始找原因,最后解決了該問題。
我們進(jìn)行問題重現(xiàn)。
我們安裝一臺(tái)新的SQL Server 2012的測(cè)試服務(wù)器,并且創(chuàng)建一個(gè)測(cè)試數(shù)據(jù)庫。然后創(chuàng)建一個(gè)包含IDENTITY列的表:
create table MyTestTable(Id int Identity(1,1), Name varchar(255));
現(xiàn)在插入兩條數(shù)據(jù):
insert into MyTestTable(Name) values ('Mr.Tom');
insert into MyTestTable(Name) values ('Mr.Jackson');
然后通過下面的查詢語句得到
SELECT Id, Name FROM MyTestTable;
目前的結(jié)果沒有問題,現(xiàn)在我們只需要重啟SQLServer服務(wù),現(xiàn)在我們從SQL Server Management Studio重啟服務(wù)。
現(xiàn)在我們將向這個(gè)表繼續(xù)插入兩條數(shù)據(jù)。
insert into MyTestTable(Name) values ('Mr.Tom2');
insert into MyTestTable(Name) values ('Mr.Jackson2');
這個(gè)時(shí)候進(jìn)行數(shù)據(jù)查詢,結(jié)果就成這樣了:
當(dāng)SQLServer2012的服務(wù)重啟后,則標(biāo)識(shí)從1002開始,這意味著它跳了1000,如果將字段設(shè)置為bigint,它會(huì)條高10000。
怎么會(huì)這樣呢,如何解決,難道是bug,但是在咨詢后,微軟聲稱這個(gè)不是bug,是一個(gè)新的功能,在某些情況下可以受益,但是對(duì)我們來說這個(gè)是不允許的,因?yàn)榭蛻舳巳绻吹竭@樣的數(shù)據(jù),肯定會(huì)覺得是一個(gè)問題,現(xiàn)在跳轉(zhuǎn)的數(shù)量取決于服務(wù)重啟的次數(shù),如果這個(gè)值在客戶端不被看到,到還好,如果被看到,那肯定需要處理。
解決方法有兩個(gè)
1:使用序列
2:配置數(shù)據(jù)庫實(shí)例的啟動(dòng)參數(shù)
1:使用序列
現(xiàn)在我們移除Identity字段,然后創(chuàng)建一個(gè)序列字段,并插入值。
CREATE SEQUENCE Id_Sequence
AS INT
START WITH 1
INCREMENT BY 1
MINVALUE 0
NO MAXVALUE
NO CACHE
2:修改數(shù)據(jù)庫實(shí)例的啟動(dòng)參數(shù)
然后修改SQLServer啟動(dòng)參數(shù),打開SQLServer configuration manager,然后選擇服務(wù)實(shí)例,點(diǎn)擊右鍵屬性,查看實(shí)例的屬性界面,然后啟動(dòng)參數(shù)選項(xiàng)輸入-t272,然后保存數(shù)據(jù)后重啟服務(wù)。這樣就可以看到差別。
這兩個(gè)方法都可以解決,但是第一種方法可以對(duì)某一個(gè)庫進(jìn)行解決,而第二個(gè)修改后,將影響整個(gè)數(shù)據(jù)庫。
如果需要調(diào)整整個(gè)數(shù)據(jù)庫,那么可以使用第二個(gè)解決方法。