【问题标题】:Autoincrement with IDENTITY not working fine on SQL Server 2008 Express带有 IDENTITY 的自动增量在 SQL Server 2008 Express 上无法正常工作
【发布时间】:2016-05-27 11:59:09
【问题描述】:

(对不起我的英语......)

我有这张桌子

CREATE TABLE [dbo].[Expedients]
(
    [IdExpedient] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    ...
)

如果我使用 8.000 寄存器表获得所有 idExpedients

select idExpedient 
from expdients 
order by idexpedients desc

计算一个idExpedient 和以下一个之间的差值(然后过滤差值 100)我得到这个:

idExp   Dif.
348376  20000
328375  10000
318345  10000
308308  9998
298121  9997
288111  9941
278098  9999
267924  9979
257752  9994
247702  9951
237694  9999
227657  9997
217639  10000
207604  9981
197576  10001
187285  9999
177285  9998
167271  9999
157268  9976
147269  10001
137268  10001
127266  10000
117248  9988
107248  10001
97181   9984
87167   9990
77102   9746
67067   9999
57038   10000
47027   9999
37013   9997
26981   10000
16979   9998

有人知道发生了什么吗?

【问题讨论】:

  • 您能告诉我们您的查询吗?
  • 记录被删除了吗?显然,那么序列中就会有间隙。
  • 是的,有时一条记录被删除但不是 10.000 条记录,这就是我过滤两个 id 之间差异超过 100 的案例的原因

标签: sql-server auto-increment


【解决方案1】:

IDENTITY 仅保证该数字始终大于前一个数字,而不是它们必然大 1。我相信这个数字被缓存在内存中,并且不会在每次分配时都写入磁盘(如果您正在执行insert into tableWithIdentity....select from otherTable,则在每次分配时写入磁盘可能会产生相当大的开销)。

我的观察是,当它从磁盘加载下一个数字时,它会使用该数字加上另一个数字来更新磁盘,比如 next + 1000(就像 Oracle 对序列及其缓存值所做的那样)。当它分配了所有这些 IDENTITY 值(在本例中为 1000 个)时,它会再次更新磁盘并添加另外 1000 个。

这意味着如果服务器在某些时间点严重关闭,则最后实际分配的数字(保证)小于下一个要分配的数字,但不会少 1。因此你可以得到差距。

请注意,任何地方的任何文档都不支持我用于缓存大小的数字 1000。我只是用它来说明我的观点。

PS:见here。该答案表明未分配的号码在服务器重新启动时总是会丢失。

【讨论】:

  • 这仅适用于2012+ sql server,显然不是这种情况。
  • 好的,所以链接的答案不合适,但我的答案是成立的。自 20 年前的 SQL Server v6.0 以来,我已经看到了这种行为。
  • 非常感谢!这就是原因...每天晚上服务器都会停下来制作文件的完整副本...
  • 为什么不定期运行备份?
猜你喜欢
  • 1970-01-01
  • 2017-07-28
  • 2012-03-14
  • 2012-10-20
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多