在MS中,很容易创建自动增量字段。在我的系统中,我停止使用自动递增字段作为主键,而现在我使用的是Guid。但是在另一个非主键字段中,我确实需要实现一个“软自动增量”。这是因为我的系统是独立于DB的,所以我用c#编程创建了autoinc值。
我想要关于数据库中没有自动增量的自动增量字段的解决方案,您使用的解决方案是什么以及为什么?有一些关于这方面的Sql声明吗?直接从我的c#生成,是一个更好的解决方案吗?
PS:我知道从表中选择max(id)+1并不是真正的并发友好.
发布于 2009-02-09 02:43:39
生成唯一id值的机制绝不能受事务隔离的限制。这是数据库为每个客户端生成一个不同的值所必需的,这比SELECT MAX(id)+1 FROM table的技巧要好,如果两个客户机试图同时分配新的id值,则会产生一个争用条件。
不能使用标准SQL查询模拟此操作(除非使用表锁或可序列化的事务)。它必须是一个内置在数据库引擎中的机制。
ANSI SQL直到SQL:2003才描述为代理键生成唯一值的操作。在此之前,还没有自动递增列的标准,因此几乎每个品牌的RDBMS都提供了一些专有的解决方案。当然,它们变化很大,没有办法以一种简单的、独立于数据库的方式使用它们。
BIGINT UNSIGNED AUTO_INCREMENT;
AUTO_INCREMENT列选项,或者相当于 Server的伪数据类型有IDENTITY列选项,NEWSEQUENTIALID()是介于自动增量和GUID之间的东西;OracleSEQUENCE 有一个SEQUENCE对象,或者SERIAL伪数据类型,它根据命名convention;GENERATOR对象,非常类似于Oracle中的SEQUENCE;Firebird2.1也支持auto-incrementing; UDB几乎都有:SEQUENCE对象,或者可以使用"GEN_ID“选项来声明列。
所有这些机制都在事务隔离之外运行,确保并发客户端获得唯一的值。此外,在所有情况下,都有一种方法可以查询当前会话最近生成的值。必须有,所以您可以使用它在子表中插入行。
发布于 2009-02-10 09:51:08
我觉得你的问题其实是个不错的问题。然而,想出一个只有SQL的解决方案是很容易迷路的。实际上,您需要使用自动增量类型的数据库实现所提供的优化和事务安全。
如果您需要提取自动增量运算符的实现,为什么不创建一个存储过程来返回您的自动增量值。大多数SQL方言都以相对相同的方式访问存储过程,并且应该更易于移植。然后,在创建sproc时,可以创建特定于数据库的自动增量逻辑--消除了将许多语句更改为特定于供应商的需要。
这样做,您的插入就可以简单到如下所示:
INSERT INTO foo (id, name, rank, serial_number)
VALUES (getNextFooId(), 'bar', 'fooRank', 123456);然后在初始化数据库时以特定于数据库的方式定义getNextFooId()。
发布于 2009-02-08 21:42:51
大多数没有自动增量字段的数据库,比如SQL Server (我特别认为是Oracle ),都有序列,您可以在这些序列中查询下一个数字。无论有多少人同时要求号码,每个人都会得到一个独特的号码。
https://stackoverflow.com/questions/526460
复制相似问题