小编典典

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

sql

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

上面的存储过程将新创建的row-id(Orders.InvoiceId)返回给调用方。

该代码运行良好,[InvoiceId]从1001开始,每个后续插入都加1。

我们的用户插入了约130行。[InvoiceId]在1130,然后在下一个插入处,其值跳至 11091

这是数据截图:

数据

我对这里发生的事情感到困惑。为什么自动加价计数器突然跳了将近10,000点?

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

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


阅读 160

收藏
2021-05-16

共1个答案

小编典典

更新感谢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);
2021-05-16