3

我是 DB/Hibernate 的新手并找到了代码:

@SequenceGenerator(name = "entSeq", allocationSize = 5, sequenceName = "CODE_SEQ")
...
    @ID
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entSeq")

为主键设置顺序。

为什么序列用于主键的值?解决了哪些目标:

  • 提高性能
  • 添加约束,一些检查
  • 限制ID整数值的可能取值范围,为什么要这样做?
  • 为什么要从1开始数?

我在以下内容中阅读了有关语法和用法的信息:

但没有找到我的问题的答案。

更新:

我喜欢阅读:

其中表明数据库理论存在问题,如何获取主键的唯一 ID。这意味着我可以在不为我自己的主键提供值的情况下插入表:

    插入供应商
    (供应商 ID,供应商名称)
    价值观
    (supplier_seq.nextval,“卡夫食品”);

但我希望此功能必须存在于所有数据库中,而不会强迫我提供主键值......

我觉得对吗?

更新2:

回答为什么使用START WITH

在将序列添加到现有数据库时,此子句很有用。当应用程序正在使用较旧的方案并且已经消耗了合法范围内的一些值时,此子句可用于跳过那些消耗的值。MINVALUE 和 MAXVALUE 用于指定合法范围,但 START WITH 将在该范围内启动序列使用,以便以前生成的值不会再次出现。

UPDATE3: *序列* 提供http://en.wikipedia.org/wiki/Surrogate_key

4

2 回答 2

1

从历史上看,有两个主要原因。

  • 避免在大表中使用 ON UPDATE CASCADE 出现性能问题。
  • 避免在广泛的自然键上连接时出现性能问题。

Oracle 甚至不支持 ON UPDATE CASCADE,因此更新用于外键引用的值比在其他平台上更麻烦。

考虑到相同大小的表格,如今这些性能“问题”比 20 年前要严重得多。(硬件现在快了很多。)但我们现在处理的表似乎比 20 年前要大得多。

这种性能调整有一些不良的副作用。

  • 与精心选择的自然键和 ON UPDATE CASCADE 相比,您通常需要更多的连接。您可能需要如此多的连接,以至于连接比磁盘读取成本更高。
  • 当您有 20 或 30 个连接时,更容易迷失在连接中。
  • 行更难快速理解。(读作 {1, 7, 13, 255, 438} 的行比读作 {1, library, checkout, 255, 'A book is your friend'} 的行更难理解。)
  • 通常,数据库设计者指定一个 ID 号作为主键,但不设置任何其他 UNIQUE 约束。这使得 ID 号成为行标识符,而不是行所代表的真实事物的标识符。这可能是个问题。
于 2012-10-16T12:06:50.740 回答
0

不能依赖所有数据库的自动生成的密钥。与大多数其他数据库不同,Oracle 不提供可用于生成顺序主键值的自动递增数据类型。
但是,使用序列和触发器可以实现相同的效果。

于 2012-10-15T06:58:24.993 回答