为什么我的自动递增的Id跳过SQL Server中的数字?

时间:2015-05-16 13:10:11

标签: sql-server sql-server-2012

它们似乎是相当大的跳跃,甚至成千上万。这是一个例子:

Exhibit A

该表的最后一个ID高于30.000标记,即使表中的行数少于一千行。

  • 造成这种情况的原因是什么?
  • 将来如何防止这种情况发生?
  • 如何阻止我现在的桌子在这条黑暗的道路上继续?

编辑:这是在我的一个旧的小型桌面应用程序中发生的,我从未删除此表中的行,也没有使用任何事务和回滚。

4 个答案:

答案 0 :(得分:8)

  

造成这种情况的原因是什么?

我想到了几个潜在的原因:

  • 行已被删除?
  • 您正在查看的结果未按id排序?
  • 标识符是在未提交的交易中分配的?
  • 数据库引擎将潜在标识符分配为内部性能调整,并且分配丢失(例如,意外的服务器重新启动)?

我可能没有想到更多可能的原因。

  

我将来如何防止这种情况发生?

取决于原因。但实际上,这是一个有争议的问题。为什么你需要"防止这个"?这种情况究竟出了什么问题?标识符不需要连续,它们只需要是唯一的。 (最好是索引顺序,否则数据库必须重新构建索引。)

  

如何阻止我现在的桌子在这条黑暗的道路上继续?

生成唯一标识符的黑暗之路?好吧,我想你可以手动提供唯一标识符。 GUID对于那种事情是好的。但是有利有弊。 (我不知道最近的实现是否已经改进了这一点,但历史上GUID并不能提供良好的聚簇索引。)

答案 1 :(得分:6)

这是在SQL服务器中设计的。 SQL Server保证生成的下一个数字将是唯一的和增量的,但不保证它将按顺序排列。

这是从SQL 2012开始的。只需重新启动服务即可重现问题。众所周知,行为的变化,一直以这种方式记录,并以设计为标志。它只是一种意想不到的行为改变

答案 2 :(得分:1)

我怀疑行已删除或插入语句已完成,使计数器递增但它们处于事务中,然后回滚。

看看这个相关的答案,看起来它也可能是由SQL Server缓存未来的身份值,然后在它有机会使用它们之前重新启动。

Identity increment is jumping in SQL Server database

答案 3 :(得分:1)

可能是由删除和回滚引起的,当您插入的数据被约束或触发器拒绝时。你不能依赖它。