- 此问题在此处已有答案**:
Identity increment is jumping in SQL Server database(6个答案)
17小时前关门了。
我在桌面上运行一个. NET堆栈,我的开发环境中有Blazor和SQL Server,在这台PC上本地运行整个堆栈和数据库。
最近我所在街区的电力一直有问题。公司正在努力解决它。停电了,当我重新打开电脑时,我注意到我的应用程序有些问题...
对于我的数据库中任何表中的每一个下一个条目,ID都变成了1004。我想可能是因为崩溃的原因,它只是增加了1000。但实际上第二天又发生了一次,此时我在每个表中有不同数量的条目,但看起来发生了完全相同的事情。下一个条目从ID 1004开始。
我知道这个电源问题并不理想,应该很快就能解决。但如果这个问题发生在购买了我的应用程序的客户身上,这将对他们的数据造成不利影响。我知道我可以使用GUID,但我听说随着这些条目的大量堆积,它会成为一个更重的资源负载。我如何才能强制ID的完整性,这是我的主键。处理这类问题的最佳方法是什么?
我已经调查了我的应用程序,以确保条目没有通过,而这停电发生,但一切看起来都很正确。这些方法通常是超级快反正,我保持SSMS的启动和运行的大部分时间。我想知道这是否可能是相关的?
2条答案
按热度按时间2vuwiymt1#
在数据库中,序列被设计为生成唯一值句点。
...或者实际上几乎是句号。它还需要:
1.尽可能快地执行此操作,使用尽可能少的计算/内存/存储资源。
1.支持多客户端并发操作。
保证序列没有间隙将违反上述要求。
您所看到的是DBMS提前保留序列值(这使得数字生成更快),但在停机期间不记得实际使用了哪些值,只记得保留了哪些值(这限制了使其工作所需的资源)的结果。
其他事件会在序列中创建间隙:
它不是序列中的间隙,而是使用该序列作为主键的表中的间隙,但是在提交
DELETE
之后,它没有任何区别。我请您想象一下,如果DBMS首先需要检查旧值是否被释放,那么序列会变慢多少。
你可能会想“那么为什么DBMS不把值放回池中以备下一次调用序列呢?”这个问题的答案是并发操作。如果DBMS必须在回滚之前检查没有其他调用序列,它也会大大降低DBMS的速度,特别是考虑到它需要线程共享信息,这在编程中从来都不容易/快速。
重复一遍:[快速+使用的最少资源+支持并发访问]的代价是序列不允许保证生成的值没有间隙;这其中很大程度上包括停电。
这肯定不会对您正在开发的应用程序产生任何负面影响,就像所有其他连接到全球数据库的应用程序一样。
tktrz96b2#
SQL Server为主键保留了1000个自动递增的数字,如果数据库服务正常停止,那么未使用的键数将被释放,但是如果数据库引擎的工作出现中断,就像你说的,那么数据库引擎使主键机制没有问题,下次执行时,它认为这1000个代码已被使用,并且这次保留1001到2000个代码。
这本身不是问题,但当您希望将主键用作序列计数器以实现传统存档等目的时,这通常会成为问题。为此,您应该考虑自己管理一个单独的字段。
有关详细信息,请参阅^、^