顺序 GUID [英] Sequential GUIDs

查看:21
本文介绍了顺序 GUID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望有人能回答这个问题.

rpcrt4.dll 类中的 UuidCreateSequential 方法如何用于为其 guid 设置种子?

我知道这么多:Microsoft 更改了 UuidCreate 函数,因此它不再使用机器的 MAC 地址作为 UUID 的一部分.由于 CoCreateGuid 调用 UuidCreate 来获取其 GUID,因此其输出也发生了变化.如果您仍然喜欢按顺序生成 GUID(有助于将相关的一组 GUID 保存在系统注册表中),您可以使用 UuidCreateSequential 函数.

问题背后的原因是.如果我使用此函数在 Web 集群中生成连续的 GUID,我如何确保 GUID 接近于一系列 GUID 而不会出现重复的 GUID?

解决方案

Win32 UuidCreateSequential 创建了一个

  • 4:随机或伪随机生成的版本 (UuidCreate)
  • 5:使用 SHA-1 散列的基于名称的版本
  • 6:RFC 4122 忘记的版本(非官方)
  • 给予:

    时间戳版本节点========================================1E163D11BE8D85D 1 80DB B8AC6FBE26E11E163D11BE8D85E 1 80DB B8AC6FBE26E11E163D11BE8D85F 1 80DB B8AC6FBE26E11E163D11BE8D860 1 80DB B8AC6FBE26E11E163D11BE8D861 1 80DB B8AC6FBE26E11E163D11BE8D862 1 80DB B8AC6FBE26E11E163D11BE8D863 1 80DB B8AC6FBE26E11E163D11BE8D864 1 80DB B8AC6FBE26E11E163D11BE8D865 1 80DB B8AC6FBE26E11E163D1220FB46C 1 80DB B8AC6FBE26E1

    最后一个包含两件事.

    低 12 位是机器特定的时钟序列编号:

    时间戳版本时钟序列节点===================================================1E163D11BE8D85D 1 8 0DB B8AC6FBE26E11E163D11BE8D85E 1 8 0DB B8AC6FBE26E11E163D11BE8D85F 1 8 0DB B8AC6FBE26E11E163D11BE8D860 1 8 0DB B8AC6FBE26E11E163D11BE8D861 1 8 0DB B8AC6FBE26E11E163D11BE8D862 1 8 0DB B8AC6FBE26E11E163D11BE8D863 1 8 0DB B8AC6FBE26E11E163D11BE8D864 1 8 0DB B8AC6FBE26E11E163D11BE8D865 1 8 0DB B8AC6FBE26E11E163D1220FB46C 1 8 0DB B8AC6FBE26E1

    在以下情况下,此机器范围的持久值会增加:

    • 你换了网卡
    • 您生成的 UUID 距离上一个不到 100 ns(并且时间戳会发生冲突)

    因此,UuidCreateSequential 创建的任何 guid 将(理想情况下)具有相同的时钟序列编号,使它们接近"彼此.

    最后的 2 位,称为 Variant,并且始终设置为二进制 10:

    时间戳版本变体时钟序列节点==========================================================1E163D11BE8D85D 1 8 0DB B8AC6FBE26E11E163D11BE8D85E 1 8 0DB B8AC6FBE26E11E163D11BE8D85F 1 8 0DB B8AC6FBE26E11E163D11BE8D860 1 8 0DB B8AC6FBE26E11E163D11BE8D861 1 8 0DB B8AC6FBE26E11E163D11BE8D862 1 8 0DB B8AC6FBE26E11E163D11BE8D863 1 8 0DB B8AC6FBE26E11E163D11BE8D864 1 8 0DB B8AC6FBE26E11E163D11BE8D865 1 8 0DB B8AC6FBE26E11E163D1220FB46C 1 8 0DB B8AC6FBE26E1

    所以你有它.顺序 guid 是顺序的;如果您在同一台机器上创建它们,它们将接近"在数据库中相互关联.


    但您想知道在不同计算机上创建的两个连续 UUID 实际会发生什么.

    利用我们对版本 1 guid 的新知识,让我们为来自不同机器的相同时间戳构建两个 guid,例如:

    {1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1}{1BE8D85D-63D1-11E1-80DB-123456789ABC}

    首先让我们插入一堆带有顺序时间戳的 guid.首先创建一个临时表来存储我们的 guid,并由 guid 组成集群:

    --DROP table #uuidOrderingTest创建表#uuidOrderingTest(uuid 唯一标识符不为空)创建聚集索引 IX_uuidorderingTest_uuid ON #uuidOrderingTest(用户名)

    现在插入数据:

    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D866-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D862-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D861-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85E-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D864-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D863-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85F-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D865-63D1-11E1-80DB-B8AC6FBE26E1}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D860-63D1-11E1-80DB-B8AC6FBE26E1}')

    注意:我以随机时间戳顺序插入它们,以说明 SQL Server 将对它们进行聚类.

    取回行并查看它们的顺序(时间戳)顺序:

    SELECT * FROM #uuidOrderingTest用户名---------------------1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E11BE8D85E-63D1-11E1-80DB-B8AC6FBE26E11BE8D85F-63D1-11E1-80DB-B8AC6FBE26E11BE8D860-63D1-11E1-80DB-B8AC6FBE26E11BE8D861-63D1-11E1-80DB-B8AC6FBE26E11BE8D862-63D1-11E1-80DB-B8AC6FBE26E11BE8D863-63D1-11E1-80DB-B8AC6FBE26E11BE8D864-63D1-11E1-80DB-B8AC6FBE26E11BE8D865-63D1-11E1-80DB-B8AC6FBE26E11BE8D866-63D1-11E1-80DB-B8AC6FBE26E1

    现在让我们插入 guid:

    • 相同的时间戳
    • 但不同的节点(即MAC地址):

    从不同的"目录插入新的 guid电脑:

    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D866-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D862-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D861-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85E-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D864-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D863-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85F-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D85D-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D865-63D1-11E1-80DB-123456789ABC}')插入 #uuidOrderingTest (uuid) 值 ('{1BE8D860-63D1-11E1-80DB-123456789ABC}')

    并得到结果:

    uuid---------------------1BE8D85D-63D1-11E1-80DB-123456789ABC1BE8D85E-63D1-11E1-80DB-123456789ABC1BE8D85F-63D1-11E1-80DB-123456789ABC1BE8D860-63D1-11E1-80DB-123456789ABC1BE8D861-63D1-11E1-80DB-123456789ABC1BE8D862-63D1-11E1-80DB-123456789ABC1BE8D863-63D1-11E1-80DB-123456789ABC1BE8D864-63D1-11E1-80DB-123456789ABC1BE8D865-63D1-11E1-80DB-123456789ABC1BE8D866-63D1-11E1-80DB-123456789ABC1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E11BE8D85E-63D1-11E1-80DB-B8AC6FBE26E11BE8D85F-63D1-11E1-80DB-B8AC6FBE26E11BE8D860-63D1-11E1-80DB-B8AC6FBE26E11BE8D861-63D1-11E1-80DB-B8AC6FBE26E11BE8D862-63D1-11E1-80DB-B8AC6FBE26E11BE8D863-63D1-11E1-80DB-B8AC6FBE26E11BE8D864-63D1-11E1-80DB-B8AC6FBE26E11BE8D865-63D1-11E1-80DB-B8AC6FBE26E11BE8D866-63D1-11E1-80DB-B8AC6FBE26E1

    所以你有它.时间戳之前的SQL Server命令的节点.从不同机器创建的 Uuid 不会聚集在一起.如果不这样做会更好,但要做什么.

    I hope someone can answer this question.

    How does the UuidCreateSequential method in the rpcrt4.dll class use to seed it's guids?

    I know this much: Microsoft changed the UuidCreate function so it no longer uses the machine's MAC address as part of the UUID. Since CoCreateGuid calls UuidCreate to get its GUID, its output also changed. If you still like the GUIDs to be generated in sequential order (helpful for keeping a related group of GUIDs together in the system registry), you can use the UuidCreateSequential function.

    The reason behind the question is. If I use this function to generate sequential GUIDs in a web cluster, how can I ensure that the GUIDs are close to a range of GUIDs without the potential of the GUID being duplicated?

    解决方案

    The Win32 UuidCreateSequential creates a Version 1 uuid.

    Here's some sample version 1 uuid's created on my computer using UuidCreateSequential:

    GuidToString                            Raw bytes
    ======================================  =================================================
    {1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 5D 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D85E-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 5E 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D85F-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 5F 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D860-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 60 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D861-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 61 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D862-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 62 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D863-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 63 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D864-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 64 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {1BE8D865-63D1-11E1-80DB-B8AC6FBE26E1}  1B E8 D8 65 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    {220FB46C-63D1-11E1-80DB-B8AC6FBE26E1}  22 0F B4 6C 63 D1 11 E1  80 DB  B8 AC 6F BE 26 E1
    

    The first thing that's important to note that these uuid contain my machine's MAC address (B8AC6FBE26E1):

                            Node
    ======================= ============
    1BE8D85D-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D85E-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D85F-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D860-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D861-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D862-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D863-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D864-63D1-11E1-80DB B8AC6FBE26E1
    1BE8D865-63D1-11E1-80DB B8AC6FBE26E1
    220FB46C-63D1-11E1-80DB B8AC6FBE26E1
    

    So if you're hoping for different computers to generate guid's that are "close" to each other, you're going to be disappointed.

    Let's look at the rest of the values.

    Seven and a half bytes of the remaining 10 bytes are a timestamp; the number of 100ns intervals since 00:00:00 15 October 1582. Rearranging those timestamp bytes together:

    Timestamp              Node
    =============== ====== ============
    1E163D11BE8D85D 1-80DB B8AC6FBE26E1
    1E163D11BE8D85E 1-80DB B8AC6FBE26E1
    1E163D11BE8D85F 1-80DB B8AC6FBE26E1
    1E163D11BE8D860 1-80DB B8AC6FBE26E1
    1E163D11BE8D861 1-80DB B8AC6FBE26E1
    1E163D11BE8D862 1-80DB B8AC6FBE26E1
    1E163D11BE8D863 1-80DB B8AC6FBE26E1
    1E163D11BE8D864 1-80DB B8AC6FBE26E1
    1E163D11BE8D865 1-80DB B8AC6FBE26E1
    1E163D1220FB46C 1-80DB B8AC6FBE26E1
    

    You can see that guid's created on the same machine by UuidCreateSequential will be together, as they are chronological.


    The 1 you see is the version number, in this case meaning a time based uuid. There are 5 defined versions:

    Giving:

    Timestamp       Version      Node
    =============== ======= ==== ============
    1E163D11BE8D85D 1       80DB B8AC6FBE26E1
    1E163D11BE8D85E 1       80DB B8AC6FBE26E1
    1E163D11BE8D85F 1       80DB B8AC6FBE26E1
    1E163D11BE8D860 1       80DB B8AC6FBE26E1
    1E163D11BE8D861 1       80DB B8AC6FBE26E1
    1E163D11BE8D862 1       80DB B8AC6FBE26E1
    1E163D11BE8D863 1       80DB B8AC6FBE26E1
    1E163D11BE8D864 1       80DB B8AC6FBE26E1
    1E163D11BE8D865 1       80DB B8AC6FBE26E1
    1E163D1220FB46C 1       80DB B8AC6FBE26E1
    

    The last word contains two things.

    The lower 12 bits is the machine-specifc Clock Sequence number:

    Timestamp       Version   Clock Sequence   Node
    =============== ======= = ================ ============
    1E163D11BE8D85D 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D85E 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D85F 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D860 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D861 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D862 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D863 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D864 1       8 0DB              B8AC6FBE26E1
    1E163D11BE8D865 1       8 0DB              B8AC6FBE26E1
    1E163D1220FB46C 1       8 0DB              B8AC6FBE26E1
    

    This machine-wide persistent value is incremented if:

    • you switched network cards
    • you generated a UUID less than 100 ns from the last one (and the timestamp would collide)

    So, again, any guid's created by UuidCreateSequential will (ideally) have the same Clock Sequence number, making them "near" to each other.

    The final 2 bits, is called a Variant, and is always set to binary 10:

    Timestamp       Version Variant Clock Sequence   Node
    =============== ======= ======= ================ ============
    1E163D11BE8D85D 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D85E 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D85F 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D860 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D861 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D862 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D863 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D864 1       8       0DB              B8AC6FBE26E1
    1E163D11BE8D865 1       8       0DB              B8AC6FBE26E1
    1E163D1220FB46C 1       8       0DB              B8AC6FBE26E1
    

    So there you have it. Sequential guid's are sequential; and if you create them on the same machine they will be "near" to each other in a database.


    But you want to know what actually happens with two sequential UUID's created on different computers.

    Using our newfound knowledge of Version 1 guids, let's construct two guid's for the same timestamp from different machines, e.g.:

    {1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1}
    {1BE8D85D-63D1-11E1-80DB-123456789ABC}
    

    First let's insert a bunch of guid's with sequential timestamps. First create a temporary table to store our guid's in, and cluster by the guid:

    --DROP table #uuidOrderingTest
    CREATE TABLE #uuidOrderingTest
    ( 
        uuid uniqueidentifier not null
    )
    
    CREATE clustered index IX_uuidorderingTest_uuid ON #uuidOrderingTest 
    ( 
       uuid
    )
    

    Now insert the data:

    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D866-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D862-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D861-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85E-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D864-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D863-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85F-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D865-63D1-11E1-80DB-B8AC6FBE26E1}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D860-63D1-11E1-80DB-B8AC6FBE26E1}')
    

    Note: i insert them in random timestamp order, to illustrate that SQL Server will cluster them.

    Get the rows back and see what order they're in sequential (timestamp) order:

    SELECT * FROM #uuidOrderingTest
    
    uuid
    ------------------------------------
    1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D85E-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D85F-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D860-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D861-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D862-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D863-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D864-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D865-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D866-63D1-11E1-80DB-B8AC6FBE26E1
    

    Now lets insert guid's with:

    • the same timestamps
    • but different node (i.e. MAC address):

    Insert the new guids from a "different" computer:

    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D866-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D862-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D861-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85E-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D864-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D863-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85F-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D85D-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D865-63D1-11E1-80DB-123456789ABC}')
    INSERT INTO #uuidOrderingTest (uuid) VALUES ('{1BE8D860-63D1-11E1-80DB-123456789ABC}')
    

    And get the results:

    uuid
    ------------------------------------
    1BE8D85D-63D1-11E1-80DB-123456789ABC
    1BE8D85E-63D1-11E1-80DB-123456789ABC
    1BE8D85F-63D1-11E1-80DB-123456789ABC
    1BE8D860-63D1-11E1-80DB-123456789ABC
    1BE8D861-63D1-11E1-80DB-123456789ABC
    1BE8D862-63D1-11E1-80DB-123456789ABC
    1BE8D863-63D1-11E1-80DB-123456789ABC
    1BE8D864-63D1-11E1-80DB-123456789ABC
    1BE8D865-63D1-11E1-80DB-123456789ABC
    1BE8D866-63D1-11E1-80DB-123456789ABC
    1BE8D85D-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D85E-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D85F-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D860-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D861-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D862-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D863-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D864-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D865-63D1-11E1-80DB-B8AC6FBE26E1
    1BE8D866-63D1-11E1-80DB-B8AC6FBE26E1
    

    So there you have it. SQL Server order's Node before Timestamp. Uuid created from different machines will not be clustered together. Would have been better if it hadn't done so, but whatcha gonna do.

    这篇关于顺序 GUID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆