繁体   English   中英

SQL Server中断分配的标识种子增量?

[英]SQL Server breaks the assigned identity seed increment?

我有两个表: table1 (列id :种子1000,增量1)和table2 (列id :种子2000,增量1)。 首先,我在table1table2插入一些记录。 其次,我在table1插入table2 (使用identity_insert_on ),并得到如下信息:

1000 first_record_table1
1001 second_record_table1
1002 third_record_table1
2000 first_record_table2
2001 second_record_table2

第三:如果我在表1中添加新记录,我希望获得1003作为新ID,但我得到2002。(1003没有违反唯一ID规则,并且是表1的正确增量值,因此我看不到任何记录跳到最后一个记录并递增1的原因,就像数据库似乎这样做的那样)。

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

关于identity文档非常清楚:

列上的identity属性不能保证满足以下条件:

  • 值的唯一性–必须通过使用PRIMARY KEY或UNIQUE约束或UNIQUE索引来强制执行唯一性。

  • 事务内的连续值–不能保证插入多行的事务会获得行的连续值,因为表上可能会发生其他并发插入。 如果值必须是连续的,则事务应在表上使用排他锁或使用SERIALIZABLE隔离级别。

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

  • 值的重用–对于具有特定种子/增量的给定身份属性,引擎不会重用身份值。 如果特定的插入语句失败或插入语句回滚,则使用的标识值将丢失并且不会再次生成。 当生成后续标识值时,这可能会导致出现间隙。

在大多数情况下, identity primary key列可以完成其预期的工作。 当插入新行时,它将创建一个大于任何先前值的新值。 可能存在差距,但这对于主键来说不是问题。

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

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

增量1仅表示下一条记录的ID比最大的ID大一个,而不是将使用所有数字。 如果要使用1003作为新ID,则必须自己进行一些编程,并处理达到2000时已经采用新ID的情况。

但是,您永远不应依赖任何生成的ID。 假设您有2节课。 第一个会话插入了一些内容,尚未提交或回滚。 第二会话插入一些东西并提交。 第一届会议回滚。 您要如何处理这种情况? 您将需要为第一个会话分配一些ID,为第二个会话分配一个不同的ID。 现在,第一个会话回滚,因此其ID未使用。 您是否要从第二个会话的ID中减去一个? 好主意。 阻止第二个会话,直到第一个会话回滚或提交? 也是个坏主意。

因此,请忘记连续的ID,它们将永远无法使用。 唯一的ID通常是您需要的,并且SQL Server保证它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM