Asp.net 数据库中的自动增量特性

Asp.net 数据库中的自动增量特性,asp.net,mysql,sql-server,database,sql-server-2005,Asp.net,Mysql,Sql Server,Database,Sql Server 2005,我使用SQL Server,当我创建一个新表时,我会使一个特定字段自动递增 主键。问题是,有人告诉我,将字段设置为主键的自动增量意味着在删除任何记录时(他们不关心自动增量字段编号),字段会增加,因此在某个点上-例如,如果我的字段类型是整数-整数的范围将被完全消耗,我将遇到麻烦。所以他们告诉我不要再使用这个功能了 最好的解决方案是通过获取我的主键的最大值来实现这一点,如果该值不存在,则最大值将是1其他方面max+1 对这个问题有什么建议吗?我可以使用自动递增功能吗 我还想知道哪些情况不适合使用自动

我使用SQL Server,当我创建一个新表时,我会使一个特定字段自动递增 主键。问题是,有人告诉我,将字段设置为主键的自动增量意味着在删除任何记录时(他们不关心自动增量字段编号),字段会增加,因此在某个点上-例如,如果我的字段类型是整数-整数的范围将被完全消耗,我将遇到麻烦。所以他们告诉我不要再使用这个功能了

最好的解决方案是通过获取我的主键的最大值来实现这一点,如果该值不存在,则最大值将是
1
其他方面
max+1

对这个问题有什么建议吗?我可以使用自动递增功能吗

我还想知道哪些情况不适合使用自动增量…以及替代方案

注意:这个问题是一般性的,不特定于任何数据库管理系统,我想知道的是,对于ORACLE、Mysql、INFORMIX等数据库管理系统也是如此

非常感谢。

您应该使用标识(自动递增)列。数据类型最多可存储2^63-1(9223372036854775807)个值。我认为您的系统不会很快达到这个值,即使您正在插入和删除大量记录


如果您正确地实施了您建议的方法,您将最终遇到许多锁定问题。否则,您将不得不处理由于违反约束而引发的异常(或者更糟的是,如果没有主键约束,则会引发非唯一值)。

继续在SQL Server中使用PK标识功能。在mysql中,也有自动递增功能。不要担心整数范围用完,否则硬盘空间就会用完。

他们建议的解决方案可能,而且很可能会造成并发问题和/或可伸缩性问题。如果两个会话同时使用您描述的Max技术,则它们可以得出相同的数字,然后两个会话都尝试同时添加该数字。这将创建约束冲突

您可以通过锁定表或捕获异常并继续重新插入来解决该问题。。但这是一种非常糟糕的做事方式。锁定会降低性能并导致可伸缩性问题(如果您计划了尽可能多的记录以担心int溢出,那么您将需要可伸缩性)

标识字段是原子操作。两个会话不能创建相同的标识字段,因此在使用它时不存在此问题

如果您担心标识字段可能溢出,那么请使用更大的数据类型,例如bigint。您将很难生成足够的记录来溢出这些记录


现在,有一些合理的理由不使用标识字段,但这不是其中之一。

SQL Server中的
int
数据类型可以保存从-2147483648到2147483647的值

如果您使用-2147483648作为标识列的种子,例如
fooididentity(-2147483648,1)
,那么您可以使用超过40亿个值

如果您真的认为这还不够,您可以使用
bigint
,它可以保存从-9223372036854775808到9223372036854775807的值,但这几乎肯定是多余的。即使有大数据量和/或大量事务,在使用
int
时,您可能会耗尽磁盘空间或耗尽应用程序的生命周期,而在使用
bigint
时几乎肯定会耗尽标识值

总之,您应该使用一个标识列,并且您不应该关心值之间的差距,因为a)您有足够的候选值,b)它是一个抽象的数字,没有逻辑意义


如果您要实现您建议的解决方案,在代码派生下一个标识列时,您将不得不考虑并发性,因为您必须同步访问两个竞争事务之间的当前最大身份值。实际上,您可能会导致性能显著下降,因为您必须先读取最大值,然后进行计算和插入(更不用说同步并发事务所涉及的额外工作)。但是,如果使用标识列,则数据库引擎将为您处理并发。

我建议不要使用标识/自动增量,因为:

  • 它的实现在SQLServer2005/2008中被破坏

  • 如果您打算使用ORM将数据库映射到对象,那么它将无法正常工作


如果您通常通过程序访问数据库,而不依赖于手动向数据库发送insert语句,我建议您使用Hi/Lo生成器。您可以在第二个链接中了解更多信息。

那么,如果PK编号顺序中存在“漏洞”,会有什么问题?谁在乎呢?@Serkan-这是一个虚幻的问题,为什么这个问题不存在,请参见下面的论点
UniqueIdentifier
当然不应该以此作为动机。它是一个16字节的值,它将消耗比
int
多4倍的空间,这在绝大多数情况下是可以接受的,是
bigint
的两倍,后者几乎总是可以接受的,但通常不是necessary@Mystere不,我没有注意到。。。如果我不这样做,那么其他人可能也不会这样做——我完全赞成在正确的时间在正确的地点开玩笑,但这很容易让人走上正轨——很多人似乎非常容易受到GUID作为身份价值观的暗示的影响…@AdamRalph,我完全同意你的看法,这不是开玩笑的好地方,这是知识的流动,如果发生这种玩笑,最终会侮辱知识。整个社会