1

次のコードは、NHibernate.Id.GuidCombGeneratorクラスにあります。アルゴリズムは、「ランダム」GUIDとDateTimeの組み合わせに基づいて、シーケンシャル(comb)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の日時フィールドに値を格納するつもりがないのに、なぜSQLServerのDateTimeの精度を気にするのでしょうか。DateTime.Nowから入手できるすべての精度を使用する方が良いのではないでしょうか。

4

2 に答える 2

4

Re 1: 実際の日の値とは関係ありません。値から使用される 2 バイトは、1900 年 1 月 1 日から 65536 日後に単純に繰り越されます。重要なのは、値がほぼ連続していることだけです。dbase は 2079 年の夏に少し非効率になるでしょうが、誰も気付かないでしょう。

Re 2: はい、意味がありません。しかし、同じ話、実際の価値は問題ではありません。

アルゴリズムには疑問があり、Guid の保証された一意性をいじることはトリッキーな命題です。これが問題なく動作するというインサイダーの知識を持っている nHibernate チームの誰かに頼る必要があります。変更すると壊れる恐れがあります。

于 2010-04-14T14:49:22.860 に答える