有很多关于如何创建对 Sql 服务器索引友好的 Guid 的方法,例如本教程。另一种流行的方法是来自 NHibernate 实现的方法(如下所列)。所以我认为编写一个实际测试此类代码的顺序需求的测试方法可能会很有趣。但我失败了——我不知道是什么构成了一个好的 Sql 服务器序列。我无法弄清楚它们是如何订购的。
例如,给定创建顺序 guid 的两种不同方式,如何确定哪种方式最好(速度除外)?例如,看起来两者都有缺点,如果他们的时钟被调回 2 分钟(例如时间服务器更新),他们的序列会突然中断?但这是否也意味着 Sql 服务器索引的麻烦?
我使用此代码生成顺序 Guid:
public static Guid CombFromArticle()
{
var randomBytes = Guid.NewGuid().ToByteArray();
byte[] timestampBytes = BitConverter.GetBytes(DateTime.Now.Ticks / 10000L);
if (BitConverter.IsLittleEndian)
Array.Reverse(timestampBytes);
var guidBytes = new byte[16];
Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
return new Guid(guidBytes);
}
public static Guid CombFromNHibernate()
{
var destinationArray = Guid.NewGuid().ToByteArray();
var time = new DateTime(0x76c, 1, 1);
var now = DateTime.Now;
var span = new TimeSpan(now.Ticks - time.Ticks);
var timeOfDay = now.TimeOfDay;
var bytes = BitConverter.GetBytes(span.Days);
var array = BitConverter.GetBytes((long)(timeOfDay.TotalMilliseconds / 3.333333));
Array.Reverse(bytes);
Array.Reverse(array);
Array.Copy(bytes, bytes.Length - 2, destinationArray, destinationArray.Length - 6, 2);
Array.Copy(array, array.Length - 4, destinationArray, destinationArray.Length - 4, 4);
return new Guid(destinationArray);
}
文章中的那个稍微快一点,但是哪个为 SQL 服务器创建了最佳序列?我可以填充 100 万条记录并比较碎片,但我什至不确定如何正确验证它。无论如何,我想了解如何编写一个测试用例来确保序列是 Sql server 定义的序列!
另外我想对这两个实现发表一些评论。是什么让一个比另一个更好?