在 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/