【问题标题】:Generated Sequential GUIDs are sometimes not sequential生成的顺序 GUID 有时不是顺序的
【发布时间】:2017-06-13 10:58:00
【问题描述】:

我有一个 C# 应用程序,它为我插入到表中的每一行生成一个顺序 GUID。我希望插入的 GUID 是连续的,但 有时 它们会破坏序列(成块)。

例子:

这些 GUID 按插入顺序显示。

为什么创建这些“顺序”GUID 时会出现如此大的顺序中断?


用于生成顺序 GUID 的代码:

class NativeMethods
{
    [DllImport("rpcrt4.dll", SetLastError = true)]
    public static extern int UuidCreateSequential(out Guid guid);
}

public static Guid CreateSequentialGuid()
    {
        const int RPC_S_OK = 0;

        Guid guid;
        int result = NativeMethods.UuidCreateSequential(out guid);
        if (result == RPC_S_OK)
            return guid;
        else
            return Guid.NewGuid(); //<--In debugging, this statement never runs.
    }

循环中用于将新的 GUID 和信息插入表中的代码:

Guid mySequentialGUID = CreateSequentialGuid();
string[] row = { item1,
                 item2,
                 item3,  
                 sourceText,
                 encoding.ToString(),
                 mySequentialGUID.ToString()
             };
var listViewItem = new ListViewItem(row);
myListView.Items.Add(listViewItem);

编辑: 请参阅此问题以了解顺序 GUID:

【问题讨论】:

  • 一个 GUID 存在是一个唯一的数字。不多也不少。虽然可以使用不同的算法来生成它们,但您不应依赖特定实现的特定属性。将 GUID 视为 GUID,不再赘述。如果您需要一个递增的数字,则获取一个数字并递增它,而不是使用 GUID,它表示一种生成唯一的方式i> 数字。
  • 我从未听说过顺序 GUID,但这似乎完全错误。这是你编的吗? GUID 就其本质而言是独一无二的,您无法控制它的生成方式。如果您知道将生成的下一个 GUID 是什么(因为它是您最后一个 GUID 的下一个),那么它不是唯一的,因为其他人可以从相同的起始值开始做同样的事情.
  • 为什么重要?只要它们仍然有序,它仍然可以工作,并且不必重新排序索引。并不是说它们会耗尽价值:)
  • 看来sequential guids 使用系统时间,所以我可以看到时钟更新时(大约每 15 毫秒)会有跳跃。
  • IMO,顺序并不意味着连续。

标签: c# guid sequential newsequentialid


【解决方案1】:

我认为问题在于您假设“顺序”的意思是“递增一”。尽管您的示例表明有时会发生这种情况,但文档中并没有实际保证会发生这种情况。我们可以争论“序列”的定义,或者这个函数的命名可能很糟糕甚至是错误的,但归根结底,根据文档,它似乎 100% 完全按照定义工作:

创建一个大于此函数先前生成的任何 GUID 的 GUID

对于对“顺序 GUID”的一般概念有疑问的人,请使用关于“遵循逻辑顺序”的“顺序”定义,并尝试记住 Melissa 病毒。这是mildly document by this line

出于安全原因,对 UuidCreate 进行了修改,使其不再使用机器的 MAC 地址来生成 UUID。引入 UuidCreateSequential 是为了允许使用机器以太网卡的 MAC 地址创建 UUID。

所以“序列”是基于 MAC 地址的 GUID。

回到 OP 的问题,我对为什么您的 GUID 每次不递增一的最佳猜测是一个简单的事实,即您可能不是唯一调用此函数的人。这是 Windows 的核心功能,必然会有其他组件、程序、服务等使用它。

【讨论】:

  • 这个答案是正确的,但我想补充一点,如果 OP 希望使用结果在 SQL Server 中插入行,她可能应该知道 UuidCreateSequential 不是完全顺序的到 SQL Server 的排序顺序,并且需要执行一些字节 suffling:blogs.msdn.microsoft.com/dbrowne/2012/07/03/…
【解决方案2】:

NewSequentialId() 在系统重新启动时重新开始。见here

创建一个大于任何 GUID 之前生成的 GUID 自 Windows 启动以来,此功能在指定计算机上。后 重新启动 Windows,GUID 可以从较低的范围再次启动,但是 仍然是全球独一无二的。当 GUID 列用作行时 标识符,使用 NEWSEQUENTIALID 可以比使用 NEWID 更快 功能。这是因为 NEWID 函数会导致随机活动 并使用更少的缓存数据页。使用 NEWSEQUENTIALID 也有助于 完全填满数据和索引页面。

【讨论】:

  • 感谢您的回答。我意识到这可能会在 Windows 重新启动后发生。我的CreateSequentialGuid() 方法在一个快速的for 循环中被调用并且我的机器没有被重新启动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-09
  • 2021-10-07
  • 1970-01-01
相关资源
最近更新 更多