mas*_*ore 10 sql sql-server primary-key
我们正在运行SQL Server 2012 SP1 x64(11.0.3000.0)
我有下表与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],
)
Run Code Online (Sandbox Code Playgroud)
通过一个简单的存储过程插入新行,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
上面的sproc将新创建的row-id(Orders.InvoiceId)返回给调用者.
代码工作正常,[InvoiceId]从1001开始,每个连续插入递增1.
我们的用户插入了大约130行.[InvoiceId]是在1130,然后在下一个插入其价值跃升至11091!
这是数据截图:

我对这里发生的事情感到困惑.为什么auto-inc计数器突然跳过近10,000点?
我们使用[InvoiceId]生成条形码的值,因此我们希望值保持在特定范围内,最好是连续的系列.
我仔细阅读了T-SQL文档,但未能找到与我的问题相关的任何内容.这是身份字段的正常行为(任意人口)吗?
更新感谢Marting&Aron,我找到了解决办法.以下是微软的官方回复:
在SQL Server 2012中,身份属性的实现已更改,以适应对其他功能的投资.在以前版本的SQL Server中,对身份生成的跟踪依赖于生成的每个身份值的事务日志记录.在SQL Server 2012中,我们分批生成标识值,并仅记录批次的最大值.这减少了写入事务日志的信息量和频率,从而提高了插入可伸缩性.
如果您需要与以前版本的SQL Server相同的标识生成语义,则有两个选项可用:
•使用跟踪标志272 o这将导致为每个生成的标识值生成日志记录.打开此跟踪标志可能会影响身份生成的性能.
•使用具有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);
Run Code Online (Sandbox Code Playgroud)
更新感谢 Martining 和 Aron,我找到了解决方法。以下是微软官方的回应:
\n\n在 SQL Server 2012 中,身份属性的实现已更改,以适应对其他功能的投资。在 SQL Server 的早期版本中,标识生成的跟踪依赖于生成的每个标识值的事务日志记录。在 SQL Server 2012 中,我们批量生成标识值并仅记录该批次的最大值。这减少了写入事务日志的信息量和频率,从而提高了插入可伸缩性。
\n\n如果您需要与以前版本的 SQL Server 相同的标识生成语义,有两个选项可用:
\n\n\xe2\x80\xa2 使用跟踪标志 272 o 这将导致为每个生成的标识值生成日志记录。打开此跟踪标志可能会影响身份生成的性能。
\n\n\xe2\x80\xa2 使用具有 NO CACHE 设置的序列生成器 ( http://msdn.microsoft.com/en-us/library/ff878091.aspx ) o 这将导致为每个生成的序列生成日志记录价值。请注意,使用 NO CACHE 可能会影响序列值生成的性能。
\n\n例子:
\n\nCREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; \nCREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL);\nRun Code Online (Sandbox Code Playgroud)\n