为SQL插入生成ID的最佳方法是什么?

时间:2009-02-24 17:47:47

标签: sql rdbms-agnostic

最好的,与DBMS无关的生成ID号的方法是什么,将立即在INSERT语句中使用,保持ID大致按顺序排列?

11 个答案:

答案 0 :(得分:10)

DBMS独立?那是个问题。两种最常用的方法是自动递增列和序列,大多数DBMS执行一个或另一个但不是两个。因此,与数据库无关的方法是让另一个表包含一个列,其中一个值可以锁定,选择,更新和解锁。

通常我会说“与DBMS独立地狱”,并使用PostgreSQL中的序列或MySQL中的自动增量列来实现。就我的目的而言,支持两者比试图找到一种适用于所有地方的方法更好。

答案 1 :(得分:6)

如果您可以用您选择的编程语言创建Globally Unique Identifier(GUID) - 请将其视为您的ID。

在排除故障时更难处理(在where条件下输入INT更容易)但也有一些优点。通过在本地分配GUID作为您的密钥,您可以轻松地构建父子记录关系,而无需先将父项保存到数据库并检索ID。由于GUID根据定义是唯一的,因此您不必担心在服务器上增加密钥。

答案 2 :(得分:1)

有自动增量或序列

这有什么意义,那是你最不担心的事情?

你将如何处理SQL本身? MySQL有限制,

SQL Server有Top,

Oracle排名

然后还有一百万个其他东西,比如触发器,alter table语法等等

答案 3 :(得分:1)

是的,原始SQL(以及我的偏好顺序)中显而易见的方法是a)序列b)自动增量字段。更好,更现代,更独立于DBMS的方法是根本不接触SQL,而是使用(好)ORM。

答案 4 :(得分:1)

没有通用的方法可以做到这一点。如果有的话,每个人都会使用它。根据定义,SQL憎恨这个想法 - 它是基于集合的逻辑的反模式(尽管在许多实际情况下是一个有用的模式)。

您尝试从其他地方插入身份值时遇到的最大问题是,当SQL语句涉及多个记录时,必须同时生成多个值。

如果您需要,请将其作为数据库选择要求的一部分,以便与您的应用程序一起使用。任何严肃的DBMS产品都将提供自己的机制,并且很容易编写DML中的差异。这些变化几乎都在DDL中。

答案 5 :(得分:1)

我总是选择特定于数据库的解决方案,但是如果你真的 通常这样做是为了实现你自己的序列。您的RDBMS必须支持事务。

您创建一个包含int列的序列表,并使用第一个数字对此进行种子处理,然后您的事务逻辑看起来像这样

begin transaction
update tblSeq set intID = intID + 1
select @myID = intID from tblSeq

inset into tblData (intID, ...) values (@myID, ...)
end transaction

事务强制写入锁定,以便在将记录插入tblData之前,下一个排队的插入不能更新tblSeq值。只要所有插入都通过此事务,那么您生成的ID就是顺序的。

答案 6 :(得分:0)

使用自动递增的id列。

答案 7 :(得分:0)

他们真的有必要按顺序排队吗?如果您只是将它用作ID,那么您应该只能使用UUID的一部分或md5的第一对数字(now())。

答案 8 :(得分:0)

你可以花时间按摩它。它等同于

DateTime.Now.Ticks

所以它就像YYYYMMDDHHMMSSSS

答案 9 :(得分:0)

这可能是一种横向方法,但一个好的ORM类型的库可能至少可以隐藏差异。例如,在Ruby中有一些ActiveRecord(通常用于但不仅仅与Ruby the Rails Web框架绑定),它具有迁移功能。在与平台无关的代码中声明的表定义中,诸如数据类型,顺序ID生成和索引创建之类的实现细节被推到了您的愿景之下。

我已经在SQLite上透明地开发了一个模式,然后在MS SQL Server上实现了它,然后移植到了Oracle。无需更改生成模式定义的代码。

正如我所说,它可能不是你想要的,但是封装不同内容的最简单方法是使用已经为你完成封装的库。

答案 10 :(得分:0)

只有SQL,以下可能是方法之一:

  1. 创建一个表格以包含您需要的起始ID
  2. 首次部署应用程序时,应用程序应在其上下文中读取值。
  3. 此后,根据需要增加id(以线程安全的方式) 3.1将id写入数据库(以线程安全的方式),它始终保持更新的值 3.2不要将其写入数据库,只是继续在内存中增加(线程安全的方式)
  4. 如果由于任何原因服务器出现故障,请将当前的id值写入数据库
  5. 当服务器再次启动时,它将从最后一次离开的位置进行选择。