【问题标题】:How should I store a GUID in Oracle?我应该如何在 Oracle 中存储 GUID?
【发布时间】:2008-09-30 16:19:24
【问题描述】:

我来自我们拥有唯一标识符的 SQL 服务器世界。 oracle中是否有等价物?此列将被频繁查询,因此性能是关键。

我在 .Net 中生成 GUID 并将其传递给 Oracle。由于几个原因,它不能由 oracle 生成,所以我不能使用序列。

【问题讨论】:

    标签: database oracle guid


    【解决方案1】:
    CREATE table test (testguid RAW(16) default SYS_GUID() ) 
    

    This blog 研究了相关性能。

    【讨论】:

    • 该博客仅将使用从数据库生成的 guid 与使用 sequence.nextval 进行比较,但我想知道使用从 .net 代码生成的 guid 时的性能如何? ?
    • 他在我回答后在第二段中添加了说明。由于索引的大小以及由于 .Net guid 的随机方面而导致索引被拆分的事实,插入可能会受到一些性能影响。如果使用原生的 Oracle 函数,那么它们是按顺序排列的,以避免类似于 SQL Server 中的函数。
    • +1 用于简明回答来源,但default SYS_GUID() 的目的是什么?我浏览了这篇文章,并不清楚该部分的用途。
    • @zarose 当插入一行并且没有为testguid列指定值时,它会通过执行SYS_GUID()函数来设置一个值。
    • @MrFox RAW(16) 相当于 .Net 中 16 个字节长的字节数组。您不必传递任何默认值,但如果您想生成并传递一个值,您可以传递如下内容: var guid = Guid.NewGuid().ToByteArray()
    【解决方案2】:

    正如其他人所说,与数字序列相比,使用 GUID 会降低性能。也就是说,自 Oracle 8i 起就有一个名为“SYS_GUID()”的函数提供了原始等效函数:

    SQL> SELECT SYS_GUID() FROM DUAL;
    
    SYS_GUID()
    --------------------------------
    248AACE7F7DE424E8B9E1F31A9F101D5
    

    可以创建一个函数来返回一个格式化的 GUID:

    CREATE OR REPLACE FUNCTION GET_FORMATTED_GUID RETURN VARCHAR2 IS guid VARCHAR2(38) ;
    BEGIN
        SELECT SYS_GUID() INTO guid FROM DUAL ;
        
        guid :=
            '{' || SUBSTR(guid,  1, 8) ||
            '-' || SUBSTR(guid,  9, 4) ||
            '-' || SUBSTR(guid, 13, 4) ||
            '-' || SUBSTR(guid, 17, 4) ||
            '-' || SUBSTR(guid, 21) || '}' ;
    
        RETURN guid ;
    END GET_FORMATTED_GUID ;
    /
    

    因此返回一个可互换的字符串:

    SQL> SELECT GET_FORMATTED_GUID() FROM DUAL ;
    
    GET_FORMATTED_GUID()
    --------------------------------------
    {15417950-9197-4ADD-BD49-BA043F262180}
    

    请注意,某些 Oracle 平台会返回相似但仍是唯一的 GUID 值 as noted by Steven Feuerstein。

    2020 年 11 月 3 日更新:Oracle 在 10g 中增加了对正则表达式函数的支持,这意味着可以使用 REGEXP_REPLACE() 函数简化连接。

    REGEXP_REPLACE(
        SYS_GUID(),
        '([0-9A-F]{8})([0-9A-F]{4})([0-9A-F]{4})([0-9A-F]{4})([0-9A-F]{12})',
        '{\1-\2-\3-\4-\5}'
    )
    

    表达式将SYS_GUID()返回的字符串值分解为5组十六进制值并重新构建,在每组之间插入一个“-”。

    【讨论】:

      【解决方案3】:

      如果我正确理解了这个问题,您希望在数据库中插入一行时生成一个唯一的 ID。
      您可以使用 sequence 来执行此操作。 link here
      创建序列后,您可以像这样使用它:

      INSERT INTO mytable (col1, col2) VALUES (myseq.NEXTVAL, 'some other data');
      

      【讨论】:

        【解决方案4】:

        RAW(16) 显然是唯一标识符 MS SQL 类型的首选等价物。

        【讨论】:

          【解决方案5】:

          GUID 在 Oracle 中不像在 MSSQL 中那样使用,我们倾向于有一个 NUMBER 字段(不是 null 和主键)、一个序列和一个插入触发器来填充它(对于每个表)。

          【讨论】:

            【解决方案6】:

            Oracle 中没有唯一标识符。

            您可以使用 RAW(有点痛苦)或 CHAR 自己实现一个。与使用整数相比,在 CHAR 字段上 JOIN 的查询的性能会受到影响(可能高达 40%)。

            如果您正在开发分布式/复制数据库,那么性能损失是值得的。否则,只需使用整数。

            【讨论】:

              【解决方案7】:

              使用 Oracle 的一般做法是创建人工密钥。这是一个定义为数字的列。它通过序列填充。它通过主键定义进行索引/约束。

              【讨论】:

                猜你喜欢
                • 2010-09-29
                • 1970-01-01
                • 2012-05-08
                • 2010-09-22
                • 1970-01-01
                • 2023-03-17
                • 1970-01-01
                • 2017-02-26
                • 1970-01-01
                相关资源
                最近更新 更多