好吧,首先:
这不是问题。
“问题”在很大程度上是设计使然。
不要,我再说一遍,不要指望 IDENTITY 列保持一组漂亮、连续的值,没有间隙。你真的不应该关心是否有差距,但它们可能是由各种各样的事情引起的。删除、回滚、failovers and service restarts 等。停止担心值并试图防止差距; IDENTITY 之所以高效工作,正是因为 SQL Server 并没有做所有防止间隙所需的额外工作。如果您想这样做,则必须手动推出自己的解决方案。
哦,重新播种不是一种选择。这就是为什么。首先,我们举一个表没有主键的例子(或者至少主键不在IDENTITY列上):
CREATE TABLE dbo.foo(id INT IDENTITY(1,1));
GO
INSERT dbo.foo DEFAULT VALUES;
GO 5
DBCC CHECKIDENT('dbo.foo', reseed, 0);
INSERT dbo.foo DEFAULT VALUES;
GO
SELECT id FROM dbo.foo ORDER BY id;
GO
DROP TABLE dbo.foo;
结果:
id
----
1
1 <-- oops! Duplicate. We probably didn't want that, right?
2
3
4
5
现在,如果 IDENTITY 列也是主键(很常见):
CREATE TABLE dbo.foo(id INT IDENTITY(1,1) PRIMARY KEY);
GO
INSERT dbo.foo DEFAULT VALUES;
GO 5
DBCC CHECKIDENT('dbo.foo', reseed, 0);
GO
INSERT dbo.foo DEFAULT VALUES;
GO
DROP TABLE dbo.foo;
哎呀:
消息 2627,第 14 级,状态 1,第 7 行
违反主键约束“PK_foo_3213E83FE3F1E24C”。无法在对象“dbo.foo”中插入重复键。重复键值为 (1)。
声明已终止。
那么你打算在那里做什么?循环直到不再出现异常?编写各种复杂的间隙和孤岛代码,找到第一个间隙,然后SET IDENTITY_INSERT ON;并手动插入值?为什么?你得到了什么?将进军速度放慢到 20 亿并溢出?我不理解这种对序列号的痴迷,并且在 IDENTITY 列中没有空白。这是一个替代的,毫无意义的价值。让我再重复一遍:
差距不是问题。
问题不在于技术。问题首先是担心差距。如果您关心差距,请停止尝试找出如何使用 IDENTITY 来防止它们;停止使用 IDENTITY,句号。或者停止关心差距。