2013-08-26 90 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

或者,也可以具有与计数器的专用表。 这不是一个好的设计模式,但它可以让你完全控制身份的工作方式。