我在ID主键上使用了Identity。 然后我插入一些数据。 例如。
数据1 - >添加成功且没有错误。 ID 1
数据2 - >添加成功且没有错误。 ID 2
数据3 - >添加失败并显示错误。
数据4 - >添加失败并显示错误。
数据5 - >添加成功且没有错误。 ID 5
您可以看到ID已从2跳到5。
为什么?怎么解决这个?
答案 0 :(得分:3)
为什么会出现这个问题?
通常,您将在主键列中使用标识。然后,这个主键是一个代理键,这意味着它绝对没有商业价值/商业意义。 它只是一个“管理”事实,为了使数据库能够唯一地识别记录,这是必要的。 所以,这个价值是什么并不重要;并且存在差距也没关系。为什么你希望它们是连续的。
并且,假设它们是连续的 - 当插入失败时没有出现间隙 - 当你删除一行时你会做什么,稍后插入一行?你也会填补空白吗?
答案 1 :(得分:0)
这是设计的,sql server首先递增计数器,然后尝试创建行,如果失败事务(总是存在隐式事务)被回滚,但不重用自动递增值。这是设计的,我会非常惊讶地看到它可以避免(最终你可以调用一些命令并将值重置为当前最大值)。你总是可以使用触发器来生成这个值,但是这会产生性能影响,通常你不应该关心auto_increment的值只是一个整数,如果你的话,你的应用程序稍后会有同样的情况
答案 2 :(得分:0)
如果插入失败,您可以在下一次插入时使用 set identity_insert mytable on 并使用max(myfield)+1手动计算下一个标识。您可能会遇到并发问题。
但这是一个淤泥。差距并没有错。
答案 3 :(得分:0)
@Frederik回答了大部分问题 - 我只想补充说你正在混淆主键和业务键。发票(或其他)应由发票编号标识 - 商业密钥应在表格中具有UNIQUE列。主键用于标识表中的一行,并且应该由数据库(加入..)和DBA使用。
向业务用户公开主键最终会遇到麻烦,数据库迟早会失去参照完整性 - 总是这样,人们很有创意。