如何从DB表中获取下一个ID而没有IDENTITY或GUID列

时间:2012-12-05 15:27:40

标签: sql sql-server transactions

我有一个包含INT主键列的表。我不想使用GUIDIDENTITY作为主键。

我想知道在不使用IDENTITYGUID作为主键列的情况下获取下一个ID的最佳方法是什么。我不介意在表格中使用GUIDIDENTITY,除非它是主键列。

我必须找到下一个可用的ID(即获取MAX ID并将其递增1),然后使用:

SELECT @id=ISNULL(max(AlbumId)+1,1) FROM Albums

但是,当我这样做时,我想阻止其他应用程序插入到表中,以便我们没有任何问题。

注意:请勿将此问题标记为 DUPLICATE 。我经历过this answer并且无法理解它。有人会善意地向我解释他们在做什么吗?我可以使用相同的技术吗?

1 个答案:

答案 0 :(得分:6)

对于SQL Server 2000 - 2008 R2,使用INT IDENTITY 远远 最简单,最可靠的方式。

尝试自己做这件事就像重新发明轮子并带着很多方式它可能会出错 - 所以为什么要这么麻烦?您需要(a)确保此机制是并发安全的(并且SELECT MAX(ID) + 1只是安全!),并且您(b)需要确保您的机制不会成为系统性能的主要瓶颈,要么......

使用INT IDENTITY作为主键有什么问题?似乎不太合理......

对于SQL Server 2012 及更新版本,您还可以考虑使用SEQUENCE(基本上是一个IDENTITY,它不是专门与单个表相关联的)

您在帖子中提到的

更新: that other SO question基本上是对SEQUENCE的“自己动手”模拟:

  • 一个表包含(sequencename, currentvalue
  • 当您要求给定序列的新值时,新值是通过使用 UPDATE语句并结合OUTPUT子句
  • 来确定的

为什么这么复杂?这是最简单,最有效的方法(除了使用IDENTITY)以安全地处理并发请求。 UPDATE语句将始终完全锁定“序列表”中的一行,以获取要从中获取新ID的序列 - 从而阻止任何其他事务获取相同的ID并获取重复的值 - 并使用ID子句将新的OUTPUT返回给调用者。