为什么我的IDENTITY列值存在差距?

时间:2013-02-01 08:04:06

标签: sql sql-server

我有一个问题。

My ID Primary(IDENTITY)配置为自动递增(type:int)。但是,当我插入一个新行时,这个新的id不是连续的。怎么了?任何解决方案?

编辑:

[...]
[id]int] IDENTITY(1,1) NOT NULL,
[...]
CONTRAINT [PK_Medida] PRIMARY KEY CLUSTERED
(
[id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

7 个答案:

答案 0 :(得分:17)

<强> The identity property on a column does not guarantee the following

值的唯一性 - 必须使用PRIMARY KEY或UNIQUE约束或UNIQUE索引强制执行唯一性。

事务中的连续值 - 插入多行的事务不能保证获得行的连续值,因为表上可能会发生其他并发插入。如果值必须是连续的,那么事务应该使用表上的独占锁或使用SERIALIZABLE隔离级别。

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

重用值 - 对于具有特定种子/增量的给定标识属性,引擎不会重用标识值。如果特定的insert语句失败或者回滚insert语句,则消耗的标识值将丢失,并且不会再次生成。生成后续标识值时,这可能会导致间隙。

同时

如果存在经常删除的表的标识列,则标识值之间可能会出现间隙。如果这是一个问题,请不要使用IDENTITY属性。但是,确保没有创建任何差距或填补现有差距,请在明确输入SET IDENTITY_INSERT ON之前评估现有的身份值。

另外,检查标识列属性&amp;检查身份增量值。它应该是1。

enter image description here

答案 1 :(得分:16)

不要指望身份是连续的。有许多情况可以留下空白。将身份视为抽象数字,不要附加任何商业含义。

答案 2 :(得分:3)

在以下时间出现差距:

  1. 记录已删除。
  2. 尝试插入时出现
  3. 错误 新记录(例如,非空约束错误)。标识值是 无助地跳过了。
  4. 有人用显式插入/更新了它 值(例如identity_insert选项)。
  5. 增量值大于1.

答案 3 :(得分:1)

您可以通过在执行增量语句之前通过评估预期错误来避免此错误<或>通过使用事务来,以便该语句永远不会被执行并且如果存在则回滚任何错误。希望它有所帮助

答案 4 :(得分:0)

新插入的行不再使用已删除行的自动ID。我不能给你一个解决方案,但这就是行为。

的Wouter

答案 5 :(得分:0)

如果列设置为主列,如果自动增量为true,则会发生这种情况,因为您可能删除了其中的某些行。如果您希望它是连续的,那么您不能使用自动增量。

答案 6 :(得分:0)

我有一个带有一些约束的表,我希望这会导致大量的insert语句失败。它导致我的索引存在巨大差距,由Identity(1,1)处理。

我设计的解决方案是创建一个没有ID列的登台表,但是包含该表的所有其他列。然后,我指定一个触发器在登台表上运行,在插入成功后,记录将转移到带索引的实际表中。在这种情况下,ID预订在不同的时间完成,并允许将所有值组合在一起作为ID。

我知道这似乎有点低效,但到目前为止它对我来说效果很好。