2013-08-26 140 views
9

我們正在運行SQL Server 2012 SP1 64位(11.0.3000.0)的SQL Server:主鍵

任意自動遞增我與InvoiceId字段作爲自動遞增,主鍵下表:

CREATE TABLE Orders(
    InvoiceId   bigint   IDENTITY(1001,1) NOT FOR REPLICATION, 
    OrderId    varchar(8)  NOT NULL, 
    ... -- other fields removed for brevity 
    CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId) 
    ON [PRIMARY], 
) 

插入新行雖然像一個簡單的存儲過程如下:

SET XACT_ABORT ON 
SET NOCOUNT ON 

BEGIN TRANSACTION 
    INSERT INTO Orders(
      OrderId, 
      ... -- other fields removed for brevity 
     ) 
    VALUES (
      @orderId, 
      ... 
     )    

    SELECT @newRowId = SCOPE_IDENTITY() 
COMMIT TRANSACTION 

上述存儲過程返回新創建的行-ID(Orders.InvoiceId)給呼叫者。

該代碼工作正常,[InvoiceId]從1001開始,每增加一個連續的插入代碼就會增加1。

我們的用戶插入了大約130行。 [InvoiceId]在1130,然後在下一個插入它的值跳到!

這裏的數據截圖:

data

我感到困惑,什麼只是發生在這裏。爲什麼汽車公司會突然跳過近10,000點?

我們使用[InvoiceId]的值生成條形碼,所以我們希望該值保持在特定的範圍內,最好是連續的系列。

我已閱讀過T-SQL文檔,但未能找到與我的問題相關的任何內容。這是身份領域的正常行爲(任意人口)嗎?

UPDATE感謝Marting &阿龍,我找到了解決辦法。下面是來自微軟的official response

在SQL Server 2012中的身份屬性的實現已經 被改變,以適應投資到其他的功能。在 之前版本的SQL Server中,身份生成跟蹤 依靠事務日誌記錄生成的每個身份值。 在SQL Server 2012中,我們分批生成標識值,並且只記錄批次的最大值 。這樣可以減少寫入事務日誌的信息的數量和頻率,提高插入的可伸縮性。

如果您需要相同的身份生成語義以前 版本的SQL Server有兩種方法可供選擇:

•使用 跟蹤標誌272Ø這將導致每個 生成的標識要生成的日誌記錄值。打開此跟蹤標誌可能會影響身份生成的性能 。

•使用序列 發生器與NO CACHE 設置(http://msdn.microsoft.com/en-us/library/ff878091.aspx)o這個 將導致對於每個生成的序列 值要生成的日誌記錄。 請注意,使用NO CACHE可能會影響序列值生成的性能 。

實施例:

CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; 
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL); 
+5

'IDENTITY'從來沒有保證連續但在2012年它可以突然躥重新啓動該服務後留下較大缺口的已知問題。 –

+0

感謝@MartinSmith!這似乎是我的情況的問題。我記得在身份增量跳躍之前重新啓動數據庫機器!我該如何避免這種情況? – masroore

+1

您無法避免它,因爲連續性從未得到保證,但您可以設置一個跟蹤標誌以獲取較慢(已記錄)的2008行爲,或者您可以使用具有較小緩存大小的序列。請參閱[此處的討論](https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-or-restart-results-in-reseed-of-identity) –

回答

2

更新由於鞅&阿龍,我找到了解決辦法。以下是微軟的官方迴應:

在SQL Server 2012中,身份屬性的實現已更改,以適應對其他功能的投資。在以前版本的SQL Server中,身份生成的跟蹤依賴於生成的每個身份值的事務日誌記錄。在SQL Server 2012中,我們分批生成標識值並僅記錄批次的最大值。這減少了寫入事務日誌的信息的數量和頻率,從而提高了插入可伸縮性。

如果您需要相同的身份生成的語義SQL Server以前的版本有兩種方法可供選擇:

•使用跟蹤標誌272Ø這將導致每個生成的標識值中產生的日誌記錄。打開此跟蹤標誌可能會影響身份生成的性能。

•使用NO CACHE設置的序列發生器(http://msdn.microsoft.com/en-us/library/ff878091.aspx)o這將導致爲每個生成的序列值生成日誌記錄。請注意,使用NO CACHE可能會影響序列值生成的性能。

例子:

CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; 
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL); 
0

或者,也可以具有與計數器的專用表。 這不是一個好的設計模式,但它可以讓你完全控制身份的工作方式。