【问题标题】:Difference Identity and Sequence/Trigger for autoincrement自动增量的差异标识和序列/触发器
【发布时间】:2016-03-09 19:22:58
【问题描述】:

我是 apex/oracle db 的新手,刚刚发现您可以使用序列 + 触发器(通常用于版本 =12c)。

什么是更好的做法,两者之间有什么区别?

谢谢:)

【问题讨论】:

  • IDENTITY 的一个优点是它在逻辑上将序列与表联系起来,如果删除表,IDENTITY 序列也会消失。但是下面提到的警告是非常有效的。即使有警告,我个人也更喜欢 IDENTITY。

标签: database oracle oracle-apex oracle12c


【解决方案1】:

一个很大的区别是处理父子插入——这里你首先需要插入父,然后在子表的插入中使用从父表生成的ID值作为外键。

在这些情况下,对于标识列,您要么需要能够使用 RETURNING 子句来取回刚刚插入的 ID(并非所有中间件都支持),要么您插入父记录然后查询获取创建的 ID,以便您可以将其用作子表中的 FK 值。如果您的表没有自然键来轻松识别刚刚插入的行 - 这可能会出现问题。

另一方面,对于这些情况,如果您不使用 IDENTITY,您可以先对序列执行 SELECT 以获得下一个增量值,然后直接在父子插入语句中使用它。这是一个更便携的解决方案,并且如果您可能需要为给定客户端安装到早期版本的 Oracle,它与所有 Oracle 版本兼容。在这种情况下,您没有触发器从序列中进行选择以设置值 - 您自己做。

是的,获取sequence.nextval 需要额外往返于数据库,但如果您的中间件不支持 RETURNING 子句,那么无论如何您都将进行往返以获取插入的 ID,并且几乎可以肯定使用更昂贵的查询。

另外,如果您有一堆使用非常方便的 %ROWTYPE 约定来操作数据的 PL/SQL 库代码,并且如果您的 IDENTITY 列设置为 GENERATED ALWAYS,那么您可能会开始遇到插入问题,如 @987654321 @。如果考虑切换到现有代码库下的 IDENTITY 列,需要注意的事项。

【讨论】:

  • 一个很好的答案,但是:“向后安装”?我不能让客户升级更不用说降级......
  • 选词不当。我的意思是,我可以在我的 12C 开发盒上使用它,但如果我的一个客户仍在 10.2 上,那么我不能向后移植身份列。
  • 有趣的答案。我还没有使用身份列,但我完全愿意尽可能避免触发器。我在插入之前使用了在 PL/SQL 中手动生成序列的方法,我真的很喜欢这种方法,但是一些 Oracle 开发人员对此有抵抗力;主要是因为他们不练习 DRY。我喜欢在可能的情况下从数据库中收回控制权并将其放入应用程序层(我认为它所属的地方)的想法。
  • 我不喜欢不必要的触发器,但我也认为存储的业务级 API 有很大的用武之地。如果需要重构后端以支持新功能,则不需要重新编写 UI,并且前端与数据库结构无关可以是安全的。如果我可以通过让事务处于业务对象级别而不是数据库对象级别来公开 pl/sql API 来限制数据库往返,那么这有助于提高等式两边的效率。
【解决方案2】:

除了问题中提到的两个(IDENTITY列和序列+触发器)还有第三种选择:即创建一个序列并在列上设置一个默认值,例如:

CREATE SEQUENCE my_sequence;

CREATE TABLE my_table
( my_column NUMBER DEFAULT my_sequence.nextval NOT NULL
, my_other_column DATE DEFAULT SYSDATE NOT NULL
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 2012-06-22
    • 2012-03-14
    相关资源
    最近更新 更多