SQL Server:主键的任意自动增量

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)

mas*_*ore 3

更新感谢 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\n
CREATE 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);\n
Run Code Online (Sandbox Code Playgroud)\n