如何在 Oracle 上生成版本 4(随机)UUID?

2024-05-14

该博客解释说,输出sys_guid()对于每个系统来说不是随机的:

http://feuerthoughts.blogspot.de/2006/02/watch-out-for-sequential-oracle-guids.html http://feuerthoughts.blogspot.de/2006/02/watch-out-for-sequential-oracle-guids.html

不幸的是我必须使用这样的系统。

如何保证获得随机的UUID?是否可以与sys_guid()?如果不是,如何在 Oracle 上可靠地获取随机 UUID?


这是一个完整的示例,基于 @Pablo Santa Cruz 的答案和您发布的代码。

我不确定您为什么收到错误消息。这可能是 SQL Developer 的问题。当您在 SQL*Plus 中运行它并添加一个函数时,一切正常:

   create or replace and compile
   java source named "RandomUUID"
   as
   public class RandomUUID
   {
      public static String create()
      {
              return java.util.UUID.randomUUID().toString();
      }
   }
   /
Java created.
   CREATE OR REPLACE FUNCTION RandomUUID
   RETURN VARCHAR2
   AS LANGUAGE JAVA
   NAME 'RandomUUID.create() return java.lang.String';
   /
Function created.
   select randomUUID() from dual;
RANDOMUUID()
--------------------------------------------------------------
4d3c8bdd-5379-4aeb-bc56-fcb01eb7cc33

但我会坚持SYS_GUID如果可能的话。查看 My Oracle Support 上的 ID 1371805.1 - 该错误据说已在 11.2.0.3 中修复。

EDIT

哪一个更快取决于函数的使用方式。

看起来 Java 版本在 SQL 中使用时速度稍快一些。但是,如果您要在 PL/SQL 上下文中使用此函数,则 PL/SQL 函数大约是 速度快两倍。 (可能是因为它避免了引擎之间切换的开销。)

这是一个简单的例子:

--Create simple table
create table test1(a number);
insert into test1 select level from dual connect by level <= 100000;
commit;

--SQL Context: Java function is slightly faster
--
--PL/SQL: 2.979, 2.979, 2.964 seconds
--Java: 2.48, 2.465, 2.481 seconds
select count(*)
from test1
--where to_char(a) > random_uuid() --PL/SQL
where to_char(a) > RandomUUID() --Java
;

--PL/SQL Context: PL/SQL function is about twice as fast
--
--PL/SQL: 0.234, 0.218, 0.234
--Java: 0.52, 0.515, 0.53
declare
    v_test1 raw(30);
    v_test2 varchar2(36);
begin
    for i in 1 .. 10000 loop
        --v_test1 := random_uuid; --PL/SQL
        v_test2 := RandomUUID; --Java
    end loop;
end;
/

版本 4 GUID 不是完全地随机的。一些字节应该是固定的。我不确定为什么这样做,或者这是否重要,但根据https://www.cryptosys.net/pki/uuid-rfc4122.html https://www.cryptosys.net/pki/uuid-rfc4122.html:

生成版本 4 UUID 的过程如下:

Generate 16 random bytes (=128 bits)
Adjust certain bits according to RFC 4122 section 4.4 as follows:
    set the four most significant bits of the 7th byte to 0100'B, so the high nibble is "4"
    set the two most significant bits of the 9th byte to 10'B, so the high nibble will be one of "8", "9", "A", or "B".
Encode the adjusted bytes as 32 hexadecimal digits
Add four hyphen "-" characters to obtain blocks of 8, 4, 4, 4 and 12 hex digits
Output the resulting 36-character string "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

Java 版本的值似乎符合标准。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Oracle 上生成版本 4(随机)UUID? 的相关文章

随机推荐