sql - 没有自动增量字段的数据库上的自动增量字段

标签 sql sql-server auto-increment ansi-sql

在 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_INCRMENT 列选项,或 SERIAL 伪数据类型,相当于 BIGINT UNSIGNED AUTO_INCRMENT
  • Microsoft SQL Server 具有 IDENTITY 列选项和 NEWSEQUENTIALID()(介于自动增量和 GUID 之间);
  • Oracle 有一个 SEQUENCE 对象;
  • PostgreSQL 有一个 SEQUENCE 对象或 SERIAL 伪数据类型,它根据命名约定隐式创建序列对象;
  • InterBase/Firebird 有一个 GENERATOR 对象,它非常类似于 Oracle 中的 SEQUENCE; Firebird 2.1 也支持 SEQUENCE
  • SQLite 将任何声明为主键的整数视为隐式自动递增;
  • DB2 UDB 几乎拥有一切:SEQUENCE 对象,或者您也可以使用“GEN_ID”选项声明列。

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

关于sql - 没有自动增量字段的数据库上的自动增量字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/526460/

相关文章:

MySQL 一对多主选

sql - 授予 SQL 作业权限,以便能够访问/修改不同服务器上的文件夹和文件

sql-server - 使用 DELETE - OUTPUT - INSERT 更新身份

mysql - 使用复合主键自动递增

php - MYSQL表自动增量

mysql - SQL 查询 MAX 值属性 1 和不同的属性 2,带有双条目过滤器

php - 如何防止 PHP 中的 SQL 注入(inject)?

c# - 在 C# Web 应用程序中插入查询超时,从 SQL Server Management Studio 运行正常

sql - 存储过程比动态查询慢

mysql - 'string' 中的 SQL 自动增量