在Oracle中生成GUID类型

日期: 2009-07-19 作者:dongqi 来源:TechTarget中国 英文

  Oracle8i引入了SYS_GUID这个概念,它同Oracle管理员所使用的传统的序列(sequence)相比具有诸多优势。一个序列生成器只是简单地创建从给定的起点开始的一系列整数值,而且它被用在选择陈述式的时候自动地递增该系列。

  序列生成器所生成的数字只能保证在单个实例里是唯一的,这就不适合将它用作并行或者远程环境里的主关键字,因为各自环境里的序列可能会生成相同的数字,从而导致冲突的发生。SYS_GUID会保证它创建的标识符在每个数据库里都是唯一的。

  此外,序列必须是DML陈述式的一部分,因此它需要一个到数据库的往返过程(否则它就不能保证其值是唯一的)。SYS_GUID源自不需要对数据库进行访问的时间戳和机器标识符,这就节省了查询的消耗。

  create table use_seq_table(id integer);
  create sequence use_seq_sequence;
  insert into use_seq_table values (use_seq_sequence_value.nextval);
  REM – for some reason, the documentation uses raw(32)
  create table use_guid_table(id raw(16));
  insert into use_guid_table(sys_guid());

  很多应用程序都依靠序列生成器来创建数据行的主关键字,这些数据行没有一个明显的主值,这也就是说,在这样的数据集里一条记录的创建就会让数据列发生改变。因此,管理员可能会对在表格中将SYS_GUID用作主关键字而不使用序列数感兴趣。这在对象在不同机器的不同数据库里生成以及需要在后来合并到一起的情况下很有用。

  但是,SYS_GUID所生成的值是一个16位的原始值。序列所生成的整数不会使用16位(的值),除非它达到了10的30次方(每个字节有两位),而且数字是相当独特的:

  SQL> select dump(123456789012345678901234567890) from dual;
  DUMP(123456789012345678901234567890)
  ————————————————————–
  Typ=2 Len=16: 207,13,35,57,79,91,13,35,57,79,91,13,35,57,79,91

  较短的值就意味着用于表格和索引的存储空间更少,以及查询访问的时间更短。

  使用SYS_GUID或者序列会在数据库使用周期里的某些地方造成性能上的消耗;问题就是在哪里。对于SYS_GUID而言,性能上的影响在查询时间和创建时间上(在表格里要创建更多的块和索引以容纳数据)。对序列而言,性能上的影响在查询期间,在这个时候,SGA序列的缓冲区被用光。在缺省情况下,一个序列一次会缓冲20个值。如果数据库没有使用这些值就关闭了,它们就会被丢失。

  SYS_GUID生成的值的另一个显著的不足之处是,管理这些值会变得困难得多。你必须(手动)输入它们或者通过脚本来填充它们,或者将它们作为Web参数来传递。

  出于这些原因,将SYS_GUID作为一个主关键字不是一个很好主意,除非是在一个并行的环境里或者希望避免使用管理序列生成器的情况下。

  在这里,我们不讨论 guid和序列器的优势,每个都会有特定环境下的需求。在Oracle9i和Oracle 10g 里SYS_GUID产生得到的数据是32 位的,如:234E45F0077881AAE0430AA3034681AA

  我这里要做的功能是将guid分割成为 Windows系统 ObjectId 的格式:{8-4-4-4-12} ,下面给出两种解决方法:

  方法一:利用substr进行分割,非常简单,具体代码如下:

  /**
  * 创建系统Object Id 格式的字符串,返回的结果如下:{234E45F0-077A-81AA-E043-0AA3034681AA}
  */
  function CreateGUID return varchar2
  is
  guid varchar(64);
  begin
  guid := SYS_GUID();
  return
  '{‘||substr(guid,1,8)||’-‘||substr(guid,9,4)||
  ’-‘||substr(guid,13,4)||’-‘||substr(guid,17,4)
  ||’-‘||substr(guid,21,12)||’}’;
  end CreateGUID;
  方法二:利用CONCAT函数进行连接,具体代码如下: 

  CREATE OR REPLACE FUNCTION GET_GUID
  RETURN CHAR
  IS
  v_guid CHAR (36);
  v_guid_part_one CHAR (8);
  v_guid_part_two CHAR (4);
  v_guid_part_three CHAR (4);
  v_guid_part_four CHAR (4);
  v_guid_part_five CHAR (12);
  BEGIN
  SELECT SYS_GUID ()
  INTO v_guid
  FROM DUAL;
  v_guid_part_one := SUBSTR (v_guid, 0, 8);
  v_guid_part_two := SUBSTR (v_guid, 8, 4);
  v_guid_part_three := SUBSTR (v_guid, 12, 4);
  v_guid_part_four := SUBSTR (v_guid, 16, 4);
  v_guid_part_five := SUBSTR (v_guid, 20, 12);
  v_guid :=
  CONCAT
  (CONCAT
  (CONCAT
  (CONCAT (CONCAT (CONCAT (CONCAT (CONCAT (v_guid_part_one,
  ’-‘),
  v_guid_part_two
  ),
  ’-‘
  ),
  v_guid_part_three
  ),
  ’-‘
  ),
  v_guid_part_four
  ),
  ’-‘
  ),
  v_guid_part_five
  );
  RETURN (v_guid);
  END GET_GUID;

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

作者

dongqi
dongqi

相关推荐

  • Notre Dame对云端SQL Server性能基准的探索实践

    确立SQL Server的性能基准,对于云端迁移来说是至关重要的第一步,一位来自于University of Notre Dame 的DBA表示,他正在试图通过数据库监控软件,找出SQL server的性能基准。

  • DBA必须掌握的数据库恢复管理技术

    如果没有备份副本,数据库管理员就无法还原数据库,所以DBA在恢复之前倾向于考虑备份是合乎逻辑的。 但是,对我来说,这种逻辑一直是错误的。

  • Azure数据湖分析从U-SQL中获得提升

    大数据的发展已经让许多精通SQL的数据专业人员不知所措。微软的U-SQL编程语言试图让这些人回归数据查询游戏。

  • TT百科:SQL(结构化查询语言)

    一般来说,SQL-on-Hadoop仍是一项新兴技术,但随着各个公司寻求获得拥有大数据应用程序编程SQL技能的开发和分析人员,它们正逐渐成为Hadoop部署的固定组件。