10

我们正在运行 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], 
)

通过一个简单的存储过程插入新行,如下所示:

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

上面的 sproc 将新创建的 row-id ( Orders.InvoiceId) 返回给调用者。

代码运行良好,[InvoiceId]从 1001 开始,每次连续插入递增 1。

我们的用户插入了大约 130 行。[InvoiceId]是 1130,然后在下一次插入时,它的值跳到11091

这是数据截图:

数据

我对这里刚刚发生的事情感到困惑。为什么自动增量计数器突然跳过近万点?

我们使用 的值[InvoiceId]来生成条形码,因此我们希望该值保持在特定范围内,最好是连续的系列。

我仔细阅读了 T-SQL 文档,但没有找到与我的问题相关的任何内容。这是身份字段的正常行为(任意人口)吗?

4

2 回答 2

3

更新感谢 Martining & 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);
于 2013-08-30T05:46:59.760 回答
0

或者,您可以使用带柜台的专用桌子。这不是一个好的设计模式,但它让您完全控制身份的工作方式。

于 2013-08-29T16:16:52.327 回答