我希望有人能回答这个问题。
rpcrt4.dll 类中的 UuidCreateSequential 方法如何用于为其 guid 提供种子?
我知道的就这么多:
Microsoft 更改了 UuidCreate 函数,因此不再使用计算机的 MAC 地址作为 UUID 的一部分。由于 CoCreateGuid 调用 UuidCreate 来获取其 GUID,因此其输出也发生了变化。如果您仍然希望按顺序生成 GUID(有助于将一组相关的 GUID 保留在系统注册表中),则可以使用 UuidCreateSequential 函数。
问题背后的原因是。如果我使用此函数在 Web 集群中生成顺序 GUID,如何确保 GUID 接近一系列 GUID,而不会出现 GUID 重复的情况?
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?
发布评论
评论(5)
Win32
UuidCreateSequential
创建一个版本1
uuid。以下是使用
UuidCreateSequential
在我的计算机上创建的一些示例版本 1 uuid:首先需要注意的是,这些 uuid 包含我计算机的 MAC 地址 (
B8AC6FBE26E1
):因此,如果您希望不同的计算机生成彼此“接近”的 guid,那么您将失望。
让我们看看其余的值。
剩下的10个字节中的7个半字节是时间戳;自 1582 年 10 月 15 日 00:00:00 起的 100 纳秒间隔数。将这些时间戳字节重新排列在一起:
您可以看到由
UuidCreateSequential
在同一台计算机上创建的 guid 将在一起,因为它们是按时间顺序排列的。您看到的
1
是版本号,在本例中表示基于时间的 uuid。有 5 个定义的版本:UuidCreateSequential
)UuidCreate
)给予:
最后 >单词包含两件事。
低 12 位是机器特定的时钟序列数字:
如果出现以下情况,则该机器范围内的持久值会递增:
因此,同样,由
UuidCreateSequential
创建的任何 guid 将(理想情况下)具有相同的时钟序列编号,使它们彼此“接近”。最后 2 位称为变体,并且始终设置为二进制
10
:所以你就知道了。顺序引导是连续的;如果您在同一台计算机上创建它们,它们在数据库中将彼此“靠近”。
但您想知道在不同计算机上创建的两个连续 UUID 实际会发生什么。
使用我们新发现的版本 1 guid 知识,让我们为来自不同机器的相同时间戳构造两个 guid,例如:
首先让我们插入一堆具有连续时间戳的 guid。首先创建一个临时表来存储我们的 guid,并通过 guid 进行集群:
现在插入数据:
注意: 我以随机时间戳顺序插入它们,以说明 SQL服务器将对它们进行集群。
返回行并查看它们的顺序(时间戳):
现在让我们插入 guid:
从“不同的”计算机插入新的指南:
并获得结果:
所以你就得到了它。 SQL Server 将节点排序在时间戳之前。从不同机器创建的 Uuid 不会聚集在一起。如果不这样做的话会更好,但是该怎么办呢?
The Win32
UuidCreateSequential
creates aVersion 1
uuid.Here's some sample version 1 uuid's created on my computer using
UuidCreateSequential
:The first thing that's important to note that these uuid contain my machine's MAC address (
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:
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:UuidCreateSequential
)UuidCreate
)Giving:
The last word contains two things.
The lower 12 bits is the machine-specifc Clock Sequence number:
This machine-wide persistent value is incremented if:
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
: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.:
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:
Now insert the data:
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:
Now lets insert guid's with:
Insert the new guids from a "different" computer:
And get the results:
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.
我通常不依赖 Win32 API,而是使用我自己的顺序 guid 变体,它将标准 guid 的八个字节替换为日期时间的刻度。
Rather than rely on the Win32 API, I typically use my own variant of a sequential guid which replaces eight bytes of the a standard guid with ticks from a datetime.
不确定 Win32 方式,但您可以使用“未记录的”“newSequentialID()'。
我说“未记录”是因为当尝试将其保存为 MSSQL Identity 列的默认值时,它被视为不正确,并且您必须覆盖它并说您想要使用它。
Not sure about the Win32 way, but you could use the 'undocumented' 'newSequentialID()' in MSSQL, if you have MSSQL Database connectivity.
I Say 'undocumented' because it's treated as incorrect when trying to save it as the default value for a MSSQL Identity column, and you have to override it and say you want to use it.
您可以有一个中心表,其中包含某个范围的最后一个已知起始 UID 并递增它。
例如:DB1 创建一个 GUID {AA333F14-FCCD-4bee-9F8F-9D9BDF1B8766} 并将其写入表中。 DB2 上线并看到 {AA333F14-FCCD-4bee-9F8F-9D9BDF1B8766} 并将其增加某个设定的数字,例如 1,000,000,000,000,000 或非常高的值,这样就不会有任何重叠的值。
但实际上,增量使用时 GUID 几乎毫无用处。
我想真正的问题是,你使用 GUID 的目的是什么?如果你想要一个递增的数字,只需使用 64 位 int(又名 bigint)
You could have a central table that has the last known starting UID for a range and increment it.
eg: DB1 creates a GUID {AA333F14-FCCD-4bee-9F8F-9D9BDF1B8766} and writes this to the table. DB2 comes online and sees {AA333F14-FCCD-4bee-9F8F-9D9BDF1B8766} and increments it by some set number, like 1,000,000,000,000,000 or something really high so you won't have any overlapping values.
But really, GUIDs are almost useless when used incrementally.
I guess the really question is, what are you using GUIDs for? If you want an incrmenting number, just use a 64bit int(aka, bigint)
我改变了 Thomas,回答将前 8 个字节作为增量
,结果将类似于
I changed Thomas, answer to have first 8 bytes as incremental
and result will be something like