3

生成将在 INSERT 语句中立即使用的 ID 号的最佳、独立于 DBMS 的方法是什么,使 ID 大致按顺序排列?

4

11 回答 11

10

DBMS 独立?那是个问题。两种最常见的方法是自动递增列和序列,大多数 DBMS 只做其中之一,但不会同时做这两个。因此,独立于数据库的方法是让另一个表具有一个具有一个值的列,您可以锁定、选择、更新和解锁。

通常我会说“与 DBMS 无关”,并使用 PostgreSQL 中的序列或 MySQL 中的自动增量列来做到这一点。就我的目的而言,支持两者都比试图找出一种适用于任何地方的方法要好。

于 2009-02-24T17:51:55.017 回答
6

如果您可以使用您选择的编程语言创建全局唯一标识符(GUID) - 将其视为您的 id。

在进行故障排除时,它们更难使用(输入whereINT 条件要容易得多),但也有一些优点。通过在本地将 GUID 分配为您的键,您可以轻松地建立父子记录关系,而无需先将父级保存到数据库并检索 id。并且由于 GUID,根据定义,是唯一的,您不必担心增加服务器上的密钥。

于 2009-02-24T17:56:09.843 回答
1

有自动递增或顺序

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

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

SQL Server 有顶级,

甲骨文有等级

然后还有一百万个其他的东西,比如触发器、改变表语法等

于 2009-02-24T17:56:00.313 回答
1

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

于 2009-02-24T17:59:03.097 回答
1

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

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

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

于 2009-02-24T18:05:20.820 回答
1

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

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

开始交易
更新 tblSeq 设置 intID = intID + 1
从 tblSeq 中选择 @myID = intID

插入 tblData (intID, ...) 值 (@myID, ...)
结束交易

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

于 2009-02-24T18:31:09.260 回答
0

使用自动递增的 id 列。

于 2009-02-24T17:50:25.677 回答
0

他们真的有理由必须按顺序排列吗?如果您只是将其用作 ID,那么您应该只能使用 UUID 的一部分或 md5(now()) 的前几个数字。

于 2009-02-24T17:56:22.790 回答
0

你可以花时间按摩它。它相当于类似的东西

DateTime.Now.Ticks

所以它就像 YYYYMMDDHHMMSSSS

于 2009-02-24T17:57:38.577 回答
0

它可能有点横向方法,但一个好的 ORM 类型库可能至少能够隐藏差异。例如,在 Ruby 中有 ActiveRecord(通常用于但不只与 Ruby the Rails Web 框架相关联),它具有迁移功能。在与平台无关的代码中声明的表定义中,数据类型、顺序 id 生成和索引创建等实现细节被推到您的视野之下。

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

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

于 2009-02-24T20:22:23.377 回答
0

仅使用 SQL,以下可能是方法之一:

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