【问题标题】:ID sequence dynamicID序列动态
【发布时间】:2023-03-05 03:16:01
【问题描述】:

我正在尝试创建一个最大编号为 999 的序列,但我面临的问题是,当我创建例如 5 个 ID 然后我删除第 3 个时,我的序列将创建 id 6,有没有触发避免空ID的方法?

例子

使用的 ID 1 2 3 4 5 我删除了3个 1 2 4 5

我做了一个插入,CURRENT 结果是 1 2 4 5 6

而我的目标是: 1 2 3 4 5

【问题讨论】:

  • 为什么这是你的目标?这没有多大意义。在添加新行(id = 6)之前,您的数据看起来像 1 2 4 5。为什么可以(显然是这样,因为您没有尝试修复它),但是 1 2 4 5 6 是不行吗?
  • 澄清我的评论:很多时候,聪明但新手开发人员认为他们必须有没有间隙的序列。这种信念是没有道理的;真正需要没有间隙的序列是非常罕见的。差距还可以。
  • 但是如果我创建了一个序列并且我只有一行 id 为 999 并且我想创建另一行(我检查了最大值为 999)如果我创建一个新的 Id 将为 1 ?
  • 即使回收id也会遇到同样的问题。如果您有 1,000 行或更多行怎么办?这就是为什么将您的 ID 限制为三位数也是一个非常糟糕的主意的原因。为什么ID不能为6位,甚至20位?

标签: sql database oracle oracle11g


【解决方案1】:

如果您确实有固定数量的资源要分配(停车场、剧院座位、酒店房间等),您会希望避免顺序并为每个资源设置一个表格。

然后您可以使用类似的方式分配资源

declare
  cursor c_res is
  select id
  from resource
  where status = 'FREE'
  order by id
  for update of status;
  v_id number;
begin
  open c_res;
  fetch c_res into v_id
  update resource
  set status = 'ALLOCATED'
  where current of c_res;
  close c_res;
end;

您需要添加错误处理以应对没有更多可用资源的情况。在处理少量、固定数量的资源时,还存在(几乎不可避免的)并发问题。

【讨论】:

    【解决方案2】:

    您绝不应该重复使用 ID。没有理由这样做,只有麻烦。 如果你真的真的需要它,你可以找到第一个可用的 ID,包括这样的间隙。但这是错误的编程习惯。您的 ID 可能也具有现实意义,在这种情况下您不应该将其称为 ID。

    select min(t1.id+1) as gap_id
        from table t1
        left join thesametable t2 on t2.id=t1.id+1
        where t2.id is null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 1970-01-01
      相关资源
      最近更新 更多