【问题标题】:Should I use Oracle's sys_guid() to generate guids?我应该使用 Oracle 的 sys_guid() 生成 guid 吗?
【发布时间】:2012-08-08 12:30:13
【问题描述】:

我有一些继承代码,每次创建实体时都会调用SELECT SYS_GUID() FROM DUAL。这意味着每次插入都会调用两次 Oracle,一次用于获取 Guid,另一次用于插入数据。

我认为这可能有一个很好的理由,例如 - Oracle 的 Guid 可能会通过顺序进行大量插入优化,因此他们可能试图避免过度的索引树重新平衡。

是否有理由使用SYS_GUID 而不是在客户端上构建自己的Guid

【问题讨论】:

  • 我可以换一种说法吗?当有本机实现时,您可能不应该构建自己的 GUID。这不是必须使用sys_guid() 的理由。它比使用序列要慢得多,并且是原始数据类型,使用起来比简单的数字更烦人。如果这仅在一个数据库中,为什么您不能对所有内容都使用单个序列?
  • 我应该清楚,我所知道的客户端上使用的所有语言都有 GUID 类型。因此,C# 中的新 Guid 由 Guid.NewGuid() 创建,而在 java 中,相同的 Guid 由 UUID.ramdomUUID() 创建。当我说“构建我自己的”时,我并不是指编写大量代码,而是创建一个新的 Guid。由于 Guid 保证是唯一的,因此不应影响它们的创建位置。这个问题仅与在 Oracle 中创建 Guid 相对于客户端的相对好处有关。我知道有(以编程方式昂贵)在插入时在 Oracle 中创建 guid 的方法

标签: oracle primary-key guid


【解决方案1】:

如果您已经为您提供了它,为什么还要自己推出它。另外,不需要先抓取再插入,直接插入即可:

create table my_tab
(
val1 raw(16),
val2 varchar2(100)
);

insert into my_tab(val1, val2) values (sys_guid(), 'Some data');
commit;

您也可以将其用作主键的默认值:

drop table my_tab;
create table my_tab
(
val1 raw(16) default sys_guid(),
val2 varchar2(100),
primary key(val1)
);

这里不需要设置插入前触发器来使用序列(或者在大多数情况下甚至不需要关心 val1 或它在代码中的填充方式)。

还对序列进行了更多维护。更不用说在系统之间移动数据时的可移植性问题。

但是,在 imo 中,序列对人类更友好(到目前为止,查看和使用数字比原始值的 32 十六进制版本更好)。序列可能还有其他好处,我没有做过任何广泛的比较,您不妨先运行一些性能测试。

【讨论】:

  • 谢谢。我了解序列相对于 Guid 的相对优势。这些好处之一是主键,尤其是集群主键受益于顺序数据(不一定是整数/数字顺序类型),因为算法经过优化以避免 btree 重新平衡。对随机数据做同样的事情显然是困难/不可能的——就像在我们的 GUID 中一样。然而, sys_guid() 看起来相当连续,尽管该序列位于 guid 的“中间”。因此问题。
【解决方案2】:

如果您关心的是两个数据库调用,您应该可以在您的INSERT 语句中调用SYS_GUID()。您甚至可以使用 RETURNING 子句来获取 Oracle 生成的值,以便将其保存在应用程序中以供进一步使用。

【讨论】:

  • 谢谢,这两个电话是我关心的问题之一。我知道我可以与插入一起生成 Guid,但这在编程上很昂贵。
  • 我想知道是否有合理的理由选择在服务器而不是客户端上创建所有 Guid 主键。
  • 只要有足够的自欺欺人,任何事情都是可以辩护的;)。我会说欢迎您在任何地方生成 GUID,而不会有人说您做错了。老实说,在某些情况下,在客户端创建 GUID 是有意义的。如果您正在进行批量加载,或者需要多个表或数据集之间的 GUID 一致。或许,如果您在不同的数据库之间工作,您可能不想在每个系统中独立创建 GUID。不过,我不知道您所说的“以编程方式昂贵”是什么意思。
【解决方案3】:

SYS_GUID 可用作主键列的默认值,这通常比使用序列更方便,但请注意这些值或多或少是随机的,而不是连续的。积极的一面,这可能会减少对热块的争用,但在消极的一面,您的索引插入也将无处不在。我们通常建议不要这样做。

供参考click here

【讨论】:

    【解决方案4】:

    我发现没有理由从 Oracle 生成 Guid。对于每个 Guid,Oracle 和客户端之间的往返可能比偶尔发生的索引重新平衡(随机值插入)要慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 2019-02-05
      • 1970-01-01
      • 2011-03-03
      相关资源
      最近更新 更多