如果我们有一个序列来为表生成唯一 ID 字段,那么这两种方法中的哪一种更有效:
- 在插入时创建一个触发器,通过从序列中获取 nextval 来填充 ID 字段。
- 在将对象(或元组)插入数据库之前,在应用层中的序列上调用 nextval。
编辑:应用程序执行大量上传。因此,假设每次应用程序运行时要插入数千或数百万行。来自 #1 的触发器会比在 #2 中提到的在应用程序中调用序列更有效吗?
如果您只关心性能,那么在 Oracle 上,使用 INSERT 语句中的序列填充 ID 通常会更快一些,而不是使用触发器,因为触发器会增加一些开销。
但是(正如 Justin Cave 所说),除非您一次插入数百万行,否则性能差异可能微不足道。测试一下看看。
由于您要插入大量行,因此最有效的方法是将 包含sequence.nextval
为 SQL 语句本身的一部分,即
INSERT INTO table_name( table_id, <<other columns>> )
VALUES( sequence_name.nextval, <<bind variables>> )
或者
INSERT INTO table_name( table_id, <<other columns>> )
SELECT sequence_name.nextval, <<other values>>
FROM some_other_table
如果您使用触发器,您将针对您插入的每一行强制将上下文从 SQL 引擎转移到 PL/SQL 引擎(然后再返回)。如果您单独获得 nextval,您将强制为每一行额外往返于数据库服务器。如果您执行一次或两次,这些都不会特别昂贵。但是,如果您将它们执行数百万次,则毫秒加起来就是实时的。
什么是钥匙?唯一标识记录的一个或多个字段应该是最终的,并且在申请过程中永远不会改变。
我区分了技术密钥和业务密钥。技术密钥在数据库上定义并生成(序列、uuid 等);业务密钥由您的域模型定义。
这就是为什么我建议
我会说如果你已经使用了休眠,那么让它控制如何使用@SequenceGenerator
and创建 id @GeneratedValue
。它将更加透明,并且 Hibernate 可以为自己保留 id,因此它可能比手动或从触发器更有效。