在MS Sql Server中很容易创建自动增量字段.在我的系统中,我停止使用自动增量字段作为主键,现在我使用Guid了.太棒了,这个改变我有很多好处.但在另一个非主要关键领域,我真的需要实现"软自动增量".这是因为我的系统与数据库无关,所以我在c#中以编程方式创建了autoinc值.
我想在没有自动增量的数据库上自动增量字段的解决方案,您使用的解决方案是什么?为什么?关于这个有一些Sql Ansi声明吗?并直接从我的c#生成,是一个更好的解决方案?
PS:我知道从表中选择max(id)+1并不是真正的并发友好...
生成唯一id值的机制不得受事务隔离.这是数据库为每个客户端生成一个不同的值所必需的,优于技巧SELECT MAX(id)+1 FROM table
,如果两个客户端尝试同时分配新id
值,则会导致竞争条件.
您无法使用标准SQL查询来模拟此操作(除非您使用表锁或可序列化事务).它必须是内置于数据库引擎中的机制.
在SQL:2003之前,ANSI SQL没有描述为代理键生成唯一值的操作.在此之前,没有自动递增列的标准,因此几乎每个品牌的RDBMS都提供了一些专有解决方案.当然它们变化很大,并且没有办法以简单的,与数据库无关的方式使用它们.
MySQL有AUTO_INCREMENT
列选项,或者SERIAL
伪数据类型,相当于BIGINT UNSIGNED AUTO_INCREMENT
;
Microsoft SQL Server具有IDENTITY
列选项,NEWSEQUENTIALID()
它在自动增量和GUID之间;
Oracle有一个SEQUENCE
对象;
PostgreSQL有一个SEQUENCE
对象或SERIAL
伪数据类型,它根据命名约定隐式创建一个序列对象;
InterBase/Firebird有GENERATOR
一个SEQUENCE
与Oracle 非常相似的对象; Firebird 2.1也支持SEQUENCE
;
SQLite将声明为主键的任何整数视为隐式自动递增;
DB2 UDB几乎包含所有内容:SEQUENCE
对象,或者您可以使用" GEN_ID
"选项声明列.
所有这些机制都在事务隔离之外运行,确保并发客户端获得唯一值.此外,在所有情况下,都有一种方法可以查询当前会话的最近生成的值.必须有,因此您可以使用它在子表中插入行.