差异标识和 Sequence/Trigger 用于自动增量

Difference Identity and Sequence/Trigger for autoincrement

我是 apex/oracle 数据库的新手,刚刚发现您可以使用序列 + 触发器(通常用于版本 < 12c)或身份列(版本 >=12c)。

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

谢谢:)

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

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

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

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

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

问题中提到的两个(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
);