关于NHibernate Guid Comb Generator的几个问题

时间:2010-04-14 12:01:53

标签: c# sql-server nhibernate guid sequential

可以在NHibernate.Id.GuidCombGenerator类中找到以下代码。该算法基于将“随机”guid与DateTime组合而创建顺序(梳状)guid。我有几个问题与我在下面标有* 1)和* 2)的行有关:

private Guid GenerateComb()
{
    byte[] guidArray = Guid.NewGuid().ToByteArray();

    // *1)
    DateTime baseDate = new DateTime(1900, 1, 1);
    DateTime now = DateTime.Now;

    // Get the days and milliseconds which will be used to build the byte string 
    TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
    TimeSpan msecs = now.TimeOfDay;

    // *2)
    // Convert to a byte array 
    // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 
    byte[] daysArray = BitConverter.GetBytes(days.Days);
    byte[] msecsArray = BitConverter.GetBytes((long) (msecs.TotalMilliseconds / 3.333333));

    // Reverse the bytes to match SQL Servers ordering 
    Array.Reverse(daysArray);
    Array.Reverse(msecsArray);

    // Copy the bytes into the guid 
    Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
    Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);

    return new Guid(guidArray);
}

首先,对于* 1),将更新的日期作为baseDate是不是更好,例如2000-01-01,以便为将来的更多价值腾出空间?

关于* 2),为什么我们关心SQL Server中的DateTimes的准确性,当我们只对datetime的字节感兴趣时,从不打算将值存储在SQL Server datetime字段中?使用DateTime.Now提供的所有准确度不是更好吗?

2 个答案:

答案 0 :(得分:4)

Re 1:与实际日期值无关,从该值中使用的两个字节仅在19,1 / 1/00之后滚动65536天。唯一重要的是价值大致是连续的。在2079年的夏天,dbase的效率会有点低,没有人会注意到。

回复2:是的,没有意义。但同样的道理,实际价值并不重要。

算法值得怀疑,搞乱Guids的保证唯一性是一个棘手的主张。你必须依赖nHibernate团队中的某个人,他们知道这个工作没有问题。如果你改变它,你可能会破坏它。

答案 1 :(得分:1)

COMB是专门为在SQL Server中有效使用GUID作为聚簇索引而创建的。这就是为什么它是围绕SQL Server特定行为编写的。

我参加这个派对的时间已经很晚了,但我认为我会分享COMB的原意。

我在04年开始使用nHibernate,我们想在我们的ID中使用GUID。经过一些研究后,我发现SQL Server无法使用完全随机的GUID作为主键/聚簇索引,因为它希望按顺序存储它们并且必须插入到表的中间(页面拆分)。我从这篇文章得到了COMB的算法:Jimmy Nilsson的http://www.informit.com/articles/article.aspx?p=25862,这是对COMB原因的一个非常全面的描述(也是一个很好的阅读)。我开始使用自定义生成器来生成COMB,然后NHibernate选择它作为内置生成器。

COMB可能无法在其他服务器中生成有序ID。我从来没有研究过它。