SQL Server打破了分配的身份种子增量



我有两个表: table1(列id:seed 1000,增量1)&table2(列id:种子2000,增量1)。首先,我将一些记录插入table1&table2。第二,我在table1(使用identity_insert_on)中插入table2,并获得类似的东西:

1000 first_record_table1
1001 second_record_table1
1002 third_record_table1
2000 first_record_table2
2001 second_record_table2

第三:如果我在Table1中添加新记录,我希望将1003作为新ID,但我获得了2002。(1003并没有打破唯一的ID规则,并且是Table1的正确增量值,因此我认为没有任何理由跳到最后一个记录并增量1,因为数据库似乎确实如此)。

问题:如何将1003作为新ID获得?

identity上的文档很清楚:

列上的身份属性不能保证以下内容:

  • 值的唯一性 - 必须使用主密钥或唯一约束或唯一索引来实现唯一性。

  • 交易中的连续值 - 不能保证插入多行的事务可以获得行的连续值,因为表格可能会在表上发生其他并发插入。如果值必须是连续的,则交易应在表上使用独家锁定或使用可序列化的隔离级别。

  • 服务器重新启动或其他故障之后的连续值-SQL Server可能出于性能原因缓存身份值,并且在数据库故障或服务器重新启动期间可能会丢失某些分配的值。这可能会导致插入时身份值的差距。如果间隙不可接受,则应用程序应使用带有Nocache选项的序列发生器或使用自己的机制生成钥匙值。

  • 重复使用值 - 对于具有特定种子/增量的给定身份属性,引擎未重复使用身份值。如果特定的插入语句失败或插入语句退缩,则消耗的身份值将丢失并且不会再次生成。当生成后续身份值时,这可能会导致空白。

在大多数情况下,identity primary key列只能执行其意图。当插入新行时,它创建的新值比任何以前的值都大。可能存在空白,但这不是主要键的问题。

如果要填补空白的列,则必须编写触发器来分配值。

另外,您可以在查询中使用row_number()获取顺序值。

增量1只是意味着下一个记录将具有比最大的ID大,而不是所有数字都将被使用。如果您希望1003作为新ID,则必须自己进行一些编程,并处理一旦达到2000,就已经采取了新的。

,但是您永远不要依靠任何没有空白的生成的ID。想象一下您有2次会议。第一次会话插入了某些内容,并且还没有提交或回滚。第二届会议插入一些东西并提交。第一次会话回滚。您想如何处理这种情况?您将需要为第一个会话分配一些ID,并为第二个会话分配不同的ID。现在,第一个会话回滚,因此其ID未使用。您想从第二会议的ID中减去一个吗?非常糟糕的主意。阻止第二会议,直到第一个会话退后或承诺?也很糟糕的主意。

所以请忘记连续的ID,它们将永远不会起作用。唯一ID是您通常需要的,SQL Server可以保证它们。

最新更新