0

如果我们有一个序列来为表生成唯一 ID 字段,那么这两种方法中的哪一种更有效:

  1. 在插入时创建一个触发器,通过从序列中获取 nextval 来填充 ID 字段。
  2. 在将对象(或元组)插入数据库之前,在应用层中的序列上调用 nextval。

编辑:应用程序执行大量上传。因此,假设每次应用程序运行时要插入数千或数百万行。来自 #1 的触发器会比在 #2 中提到的在应用程序中调用序列更有效吗?

4

4 回答 4

2

如果您只关心性能,那么在 Oracle 上,使用 INSERT 语句中的序列填充 ID 通常会更快一些,而不是使用触发器,因为触发器会增加一些开销。

但是(正如 Justin Cave 所说),除非您一次插入数百万行,否则性能差异可能微不足道。测试一下看看。

于 2012-10-17T07:11:13.953 回答
2

由于您要插入大量行,因此最有效的方法是将 包含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,您将强制为每一行额外往返于数据库服务器。如果您执行一次或两次,这些都不会特别昂贵。但是,如果您将它们执行数百万次,则毫秒加起来就是实时的。

于 2012-10-17T07:13:25.793 回答
0

什么是钥匙?唯一标识记录的一个或多个字段应该是最终的,并且在申请过程中永远不会改变。

我区分了技术密钥和业务密钥。技术密钥在数据库上定义并生成(序列、uuid 等);业务密钥由您的域模型定义。

这就是为什么我建议

  • 始终在数据库上生成带有序列/触发器的技术 PK
  • 切勿在您的应用程序中使用此 PK 字段(提示:标记 getId() setId() @Deprecated )
  • 定义唯一标识您的实体的业务字段并在 equals/hashcode 方法中使用这些字段
于 2012-10-17T07:02:04.990 回答
0

我会说如果你已经使用了休眠,那么让它控制如何使用@SequenceGeneratorand创建 id @GeneratedValue。它将更加透明,并且 Hibernate 可以为自己保留 id,因此它可能比手动或从触发器更有效。

于 2012-10-17T07:15:06.763 回答