Oracle的SYS_GUID() UUID符合RFC 4122标准吗?

32

我想知道 Oracle 的 SYS_GUID() 函数是否返回符合RFC 4122标准的UUID。例如:

SQL> select sys_guid() from dual;

SYS_GUID()
--------------------------------
A6C1BD5167C366C6E04400144FD25BA0

我知道,SYS_GUID()返回一个16字节的RAW数据类型。Oracle使用RAWTOHEX()和可能的TO_CHAR()将上述ID打印出来。这是否可以理解为符合UUID格式的字符串格式:

A6C1BD51-67C3-66C6-E044-00144FD25BA0
我认为这不符合RFC 4122标准,因为定义规定,有效的UUID必须在UUID本身内命名UUID版本。
符合RFC 4122标准的UUID语法(第3版):
xxxxxxxx-xxxx-3xxx-xxxx-xxxxxxxxxxxx

1
SYS_GUID返回一个RAW数据类型。客户端(如sqlplus)将其渲染成可读格式。 - Gary Myers
4个回答

27

如果您想要那种格式,请尝试这个:

select regexp_replace(rawtohex(sys_guid())
       , '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})'
       , '\1-\2-\3-\4-\5') 
         as FORMATTED_GUID 
 from dual

示例结果:

 FORMATTED_GUID                                                                  
 ------------------------------------
 F680233E-0FDD-00C4-E043-0A4059C654C9  

2
为了通过避免使用REGEXP来进行批量数据处理以获得更好的性能,请参见此处 - Marmite Bomber
1
这不是一个有效的版本3 UUID,因为它应该具有格式xxxxxxxx-xxxx-3xxx-xxxx-xxxxxxxxxxxx(版本3)或xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx(版本4)。 - ZerOne

25

SYS_GUID是Oracle的等同于UUID的概念。它具有全局唯一性。但是,它不符合RFC 4122标准;我从文档中没有提到UUID(除了Java XML文档)推断出其不符合标准。

我怀疑Oracle没有原生实现RFC 4122是因为他们认为它不可扩展。否则,他们为什么要发明自己的东西而不遵循标准呢?


4

如果有足够的权限,Oracle可以生成符合标准的UUID。

1. 通过定义SQL函数

https://dev59.com/cmYr5IYBdhLWcg3wG2lI#13956771得知,您可以执行以下操作:

create or replace function random_uuid return RAW is
  v_uuid RAW(16);
begin
  v_uuid := sys.dbms_crypto.randombytes(16);
  return (utl_raw.overlay(utl_raw.bit_or(utl_raw.bit_and(utl_raw.substr(v_uuid, 7, 1), '0F'), '40'), v_uuid, 7));
end random_uuid;

该函数需要dbms_cryptoutl_raw,两者都需要执行授权。

grant execute on sys.dbms_crypto to uuid_user;

2. 使用Java过程

要创建符合规范的UUID的Java过程,请参见https://dev59.com/cmYr5IYBdhLWcg3wG2lI#13951615


1

RFC 4122 § 3. 命名空间注册模板(第5页)

验证机制:
除了确定UUID的时间戳部分是否在将来,因此不可分配之外,没有机制来确定UUID是否“有效”。

符合RFC 4122的“规范性”取决于生成过程,UUID本身只是一个128位的IDentifier。

因此,答案是肯定的,为什么不符合要求呢? UUID 只是一个 128 位的通用唯一标识符,规范的其余部分只是推荐的方式,以帮助您/Oracle 生成与其他生成 U.U. ID 标识符不冲突的标识符。 如果您或 Oracle 不想遵循他们的建议,他们可以自由选择。 无论如何,您提供的 UUID 与 RFC 4122“符合要求”,因为变体字段以比特序列 111 开始,该序列是“保留供未来定义使用”的。 规范是过去编写的,不限制谁可以指定“未来定义”,它当然不会阻止 Oracle 定义自己的变体...因此它是“符合要求”的...哈哈。

附言:我喜欢原作者预见到了你的问题,并在“有效”一词周围添加了讽刺引号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接