使用触发器生成ID与手动创建ID

时间:2012-10-17 06:51:30

标签: java sql oracle hibernate

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

  1. 在insert上创建一个触发器,通过从序列中获取nextval来填充ID字段。
  2. 在将对象(或元组)插入数据库之前,在应用程序层中调用nextval。
  3. 编辑:应用程序执行批量上传。因此,假设每次应用程序运行时都要插入数千或数百万行。来自#1的触发器是否比在#2中提到的应用程序中调用序列更有效?

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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,则会强制为每一行额外往返数据库服务器。如果你这样做一次或两次,这些都不是特别昂贵。但是,如果你这样做了数百万次,则毫秒加起来就是实时的。

答案 2 :(得分:0)

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

我在技术密钥和业务密钥之间做出了贡献。技术密钥在数据库上定义并生成(序列,uuid等);业务键由您的域模型定义。

这就是我建议的原因

  • 始终使用数据库中的序列/触发器生成技术PK
  • 永远不要在你的应用程序中使用这个PK字段(提示:标记getId() setId()@Deprecated)
  • 定义唯一标识您的实体的业务字段,并在equals / hashcode方法中使用这些

答案 3 :(得分:0)

我会说如果您已经使用了hibernate,那么让它控制如何使用@SequenceGenerator@GeneratedValue创建ID。它会更透明,Hibernate可以为自己保留id,所以它可能比手动或触发更有效。