我们正在运行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,然后在下一个插入它的值跳到!
这里的数据截图:
我感到困惑,什么只是发生在这里。为什么汽车公司会突然跳过近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);
'IDENTITY'从来没有保证连续但在2012年它可以突然蹿重新启动该服务后留下较大缺口的已知问题。 –
感谢@MartinSmith!这似乎是我的情况的问题。我记得在身份增量跳跃之前重新启动数据库机器!我该如何避免这种情况? – masroore
您无法避免它,因为连续性从未得到保证,但您可以设置一个跟踪标志以获取较慢(已记录)的2008行为,或者您可以使用具有较小缓存大小的序列。请参阅[此处的讨论](https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-or-restart-results-in-reseed-of-identity) –