首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有自动增量字段的数据库上的AutoIncrement字段

没有自动增量字段的数据库上的AutoIncrement字段
EN

Stack Overflow用户
提问于 2009-02-08 21:36:51
回答 5查看 11K关注 0票数 9

在MS中,很容易创建自动增量字段。在我的系统中,我停止使用自动递增字段作为主键,而现在我使用的是Guid。但是在另一个非主键字段中,我确实需要实现一个“软自动增量”。这是因为我的系统是独立于DB的,所以我用c#编程创建了autoinc值。

我想要关于数据库中没有自动增量的自动增量字段的解决方案,您使用的解决方案是什么以及为什么?有一些关于这方面的Sql声明吗?直接从我的c#生成,是一个更好的解决方案吗?

PS:我知道从表中选择max(id)+1并不是真正的并发友好.

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-02-09 02:43:39

生成唯一id值的机制绝不能受事务隔离的限制。这是数据库为每个客户端生成一个不同的值所必需的,这比SELECT MAX(id)+1 FROM table的技巧要好,如果两个客户机试图同时分配新的id值,则会产生一个争用条件。

不能使用标准SQL查询模拟此操作(除非使用表锁或可序列化的事务)。它必须是一个内置在数据库引擎中的机制。

ANSI SQL直到SQL:2003才描述为代理键生成唯一值的操作。在此之前,还没有自动递增列的标准,因此几乎每个品牌的RDBMS都提供了一些专有的解决方案。当然,它们变化很大,没有办法以一种简单的、独立于数据库的方式使用它们。

BIGINT UNSIGNED AUTO_INCREMENT;

  • Microsoft

  • MySQL有AUTO_INCREMENT列选项,或者相当于 Server的伪数据类型有IDENTITY列选项,NEWSEQUENTIALID()是介于自动增量和GUID之间的东西;Oracle
  • 有一个SEQUENCE 有一个SEQUENCE对象,或者SERIAL伪数据类型,它根据命名convention;
    • InterBase/Firebird隐式创建一个序列对象,它有一个GENERATOR对象,非常类似于Oracle中的SEQUENCE;Firebird2.1也支持auto-incrementing;
    • DB2;
    • SQLite将声明为主键的任何整数视为隐式的

    UDB几乎都有:SEQUENCE对象,或者可以使用"GEN_ID“选项来声明列。

所有这些机制都在事务隔离之外运行,确保并发客户端获得唯一的值。此外,在所有情况下,都有一种方法可以查询当前会话最近生成的值。必须有,所以您可以使用它在子表中插入行。

票数 16
EN

Stack Overflow用户

发布于 2009-02-10 09:51:08

我觉得你的问题其实是个不错的问题。然而,想出一个只有SQL的解决方案是很容易迷路的。实际上,您需要使用自动增量类型的数据库实现所提供的优化和事务安全。

如果您需要提取自动增量运算符的实现,为什么不创建一个存储过程来返回您的自动增量值。大多数SQL方言都以相对相同的方式访问存储过程,并且应该更易于移植。然后,在创建sproc时,可以创建特定于数据库的自动增量逻辑--消除了将许多语句更改为特定于供应商的需要。

这样做,您的插入就可以简单到如下所示:

代码语言:javascript
复制
INSERT INTO foo (id, name, rank, serial_number)
 VALUES (getNextFooId(), 'bar', 'fooRank', 123456);

然后在初始化数据库时以特定于数据库的方式定义getNextFooId()。

票数 2
EN

Stack Overflow用户

发布于 2009-02-08 21:42:51

大多数没有自动增量字段的数据库,比如SQL Server (我特别认为是Oracle ),都有序列,您可以在这些序列中查询下一个数字。无论有多少人同时要求号码,每个人都会得到一个独特的号码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/526460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档