为什么 ef 中的身份号码会跳到一个很大的数字?
为什么 ef 中的身份号码会跳到一个很大的数字?
我在我的网站上使用了Entity Framework 6.0。
我有一个表用于插入一些数据,这个表有一个标识列,如ID(int),我的标识种子等于1;
有时候,当我在SQL管理工具中查看这个表时,我发现这个ID跳到了一个很大的数值,例如从30跳到10024。
为什么会发生这种情况?这是一个bug吗?
我在这里贴出了我的示例代码,通过一些代码像这样向表中插入数据:
using (var context = new MyModelDBEntities()) { mytable mt=new mytable; mt.name=""; //例如 context.mytables.add(mt); context.SaveChanges(); }
这段代码正常吗?我的表发生了什么,标识号为什么跳到一个很大的数值?
问题的出现的原因:在SQL Server中,identity属性不保证列的值是连续的。在数据库故障或服务器重启时,SQL Server可能会缓存identity值,导致在插入数据时一些已分配的值丢失,从而导致identity值出现间隔。另外,如果插入语句失败或回滚,则已消耗的identity值将丢失,不会再次生成,从而导致后续的identity值出现间隔。
解决方法:如果不接受identity值出现间隔,可以使用序列生成器(sequence generator)并设置NOCACHE选项,或者使用自定义机制生成主键值。
以下是整理的
在SQL Server中,identity属性不保证列的值是连续的。根据官方文档的说明,identity值在数据库故障或服务器重启时可能会有缓存,这可能导致已分配的值丢失,从而在插入数据时出现identity值的间隔。此外,如果插入语句失败或回滚,则已消耗的identity值将丢失,不会再次生成,也会导致identity值的间隔。
为了解决这个问题,官方文档给出了两种解决方法。首先,可以使用序列生成器(sequence generator)来代替identity属性生成主键值。在使用序列生成器时,需要设置NOCACHE选项,这样可以确保在数据库故障或服务器重启后不会丢失已分配的值,从而避免identity值的间隔。
另外一种解决方法是使用自定义机制来生成主键值。通过自定义机制,我们可以控制主键值的生成过程,确保不会出现identity值的间隔。这种方法需要根据具体的需求和业务逻辑来实现,可以根据需要使用各种算法和规则来生成主键值。
,如果不接受identity值出现间隔,可以使用序列生成器并设置NOCACHE选项,或者使用自定义机制生成主键值。这样可以确保在数据库故障或服务器重启时不会丢失已分配的值,从而避免identity值的间隔。
问题的出现可能有很多原因,其中之一可能是尝试插入9,994条记录失败了,或者多次尝试插入的总记录数达到了9,994条。身份列并不保证连续的ID,它只保证唯一的ID。如果插入尝试失败了(或者是一个回滚的事务的一部分),那么本应生成的ID就不会被重新使用。另一个可能是在使用SET IDENTITY_INSERT ON
之后插入了一个特定的ID。无论如何,你有超过20亿个可用的ID,所以差距10,000左右不应该引起警报。如果随着时间的推移,这些间隔越来越大,那么可能会有更大的问题,因为这些间隔可能会呈指数增长。有时会出现一个bug,间隔等于表中当前记录的数量,所以这些“间隔”会呈指数增长,导致比间隔一致时更快达到20亿的限制。这种情况很少见(通常只在使用SET IDENTITY_INSERT ON
时才会发生),但值得注意。但在这种情况下似乎不太可能发生,因为你从30跳到了10,000。我敢打赌这是由于插入失败造成的。如果任何代码、定时作业或SQL脚本使用了SET IDENTITY_INSERT myTable ON
,那么它们可以插入任何想要的值,并且在调用SET IDENTITY_INSERT myTable OFF
之后,身份列会被重新设置为该身份列中的最大值。这是一个展示了失败插入和身份插入导致间隔的SQL Fiddle。这个问题的答案仍然没有回答到PO的问题。在我的小项目中,我只进行简单的CRUD操作,我很确定我没有1000个失败的插入,并且从未使用过SET IDENTITY_INSERT myTable OFF
。更有可能是Microsoft产品的一些内部问题。无法再对此进行更多解释=> 1,2,3,4,5,6,7,1002,1003,1004
。