Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为SQL插入生成ID的最佳方法是什么?_Sql_Rdbms Agnostic - Fatal编程技术网

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

为SQL插入生成ID的最佳方法是什么?,sql,rdbms-agnostic,Sql,Rdbms Agnostic,生成将立即在INSERT语句中使用的ID号的最佳、独立于DBMS的方法是什么,以使ID大致保持顺序?使用自动递增的ID列。独立于DBMS?这是个问题。最常用的两种方法是自动递增列、列和序列,大多数DBMS都会执行其中一种方法,但不能同时执行这两种方法。因此,独立于数据库的方法是,使用另一个表,其中一列包含一个值,您可以锁定、选择、更新和解锁该值 通常我会说“让DBMS独立见鬼去吧”,然后在PostgreSQL中使用序列,或者在MySQL中使用自动增量列。就我的目的而言,支持两者总比试图找到一种在

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

使用自动递增的ID列。

独立于DBMS?这是个问题。最常用的两种方法是自动递增列、列和序列,大多数DBMS都会执行其中一种方法,但不能同时执行这两种方法。因此,独立于数据库的方法是,使用另一个表,其中一列包含一个值,您可以锁定、选择、更新和解锁该值


通常我会说“让DBMS独立见鬼去吧”,然后在PostgreSQL中使用序列,或者在MySQL中使用自动增量列。就我的目的而言,支持两者总比试图找到一种在任何地方都有效的方法要好。

有自动递增或顺序

你最不担心的问题是什么

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

SQL Server具有顶级

甲骨文有地位

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

< p>如果你可以用你所选择的编程语言创建一个(GUID)——把它看作你的ID.<
在进行故障排除时,它们更难使用(键入INT的
条件要容易得多),但也有一些优点。通过在本地将GUID指定为密钥,您可以轻松构建父子记录关系,而无需首先将父记录保存到数据库并检索id。而且,根据定义,GUID是唯一的,您不必担心增加服务器上的密钥。

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

您可以花时间对其进行按摩。这相当于

DateTime.Now.Ticks

所以它可能类似于yyyymmddhhmmsss

是的,原始SQL中的明显方式(按照我的偏好顺序)是a)序列b)自动递增字段。更好、更现代、更独立于DBMS的方法是完全不接触SQL,而是使用(好的)ORM。

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

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


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

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

创建一个包含int列的序列表,并用第一个数字作为种子,事务逻辑如下所示

begin transaction update tblSeq set intID = intID + 1 select @myID = intID from tblSeq inset into tblData (intID, ...) values (@myID, ...) end transaction 开始交易 更新tblSeq set intID=intID+1 从tblSeq中选择@myID=intID 插入tblData(intID,…)值(@myID,…) 结束交易
该事务强制写入锁定,以便在将记录插入tblData之前,下一次排队插入无法更新tblSeq值。只要所有的插入都经过这个事务,那么您生成的ID是按顺序的。

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

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


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

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

  • 创建一个表以包含您需要的起始id
  • 第一次部署应用程序时,应用程序应在其上下文中读取该值
  • 此后,根据需要增加id(以线程安全方式) 3.1将id写入始终保持更新值的数据库(以线程安全方式) 3.2不要将其写入数据库,只需在内存中保持增量(线程安全方式)
  • 如果由于任何原因服务器停机,请将当前id值写入数据库
  • 当服务器再次启动时,它将从上次离开的位置进行拾取

  • 我认为“DBMS独立”的意思是不可能自动增加列。生成这样一个列的语法对于所有常见的数据库来说都是不同的。许多流行的DBMS没有任何类型的自动增量列类型。这真的非常痛苦。我没有更好的DBMS独立解决方案,但我在某些地方看到过这种设计,这种设计无法很好地扩展(或者至少我没有看到它工作得很好)。我希望我的SQL脚本尽可能可移植。我想我是在寻找一个根本不存在的标准化水平。确保在两个用户同时插入一条记录的罕见事件中也包含某种类型的机器id。不可能,但仍然可能。如果时钟分辨率不够快,批量插入可能会成为一个问题。许多唱片公司