public sealed class SequentialGuid
{
//使用 Guid.NewGuid() 的字节重排
/// <summary>
/// 优点及适用场景:
/// 1.系统只在应用层生成GUID,追求极致的插入性能和最低的索引碎片
/// 2.系统并发量极高,需要最高的时间戳精度来避免冲突(因为使用系统滴答计数(Tick),精度为100纳秒)
/// </summary>
/// <param name="guidType"></param>
/// <returns></returns>
public static Guid Create(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
{
var randomBytes = Guid.NewGuid().ToByteArray();
var timeBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
if (BitConverter.IsLittleEndian)
Array.Reverse(timeBytes);
byte[] sequentialBytes;
switch (guidType)
{
case SequentialGuidType.SequentialAsString:
case SequentialGuidType.SequentialAsBinary:
sequentialBytes = new byte[16];
Buffer.BlockCopy(timeBytes, 2, sequentialBytes, 0, 6);
Buffer.BlockCopy(randomBytes, 0, sequentialBytes, 6, 10);
break;
case SequentialGuidType.SequentialAtEnd:
sequentialBytes = new byte[16];
Buffer.BlockCopy(randomBytes, 0, sequentialBytes, 0, 10);
Buffer.BlockCopy(timeBytes, 2, sequentialBytes, 10, 6);
break;
default:
throw new ArgumentOutOfRangeException("guidType");
}
return new Guid(sequentialBytes);
}
public enum SequentialGuidType
{
SequentialAsString,
SequentialAsBinary,
SequentialAtEnd
}
//使用 Comb GUID 算法
/// <summary>
/// 优点及适用场景:
/// 1.需要与SQL Server NEWSEQUENTIALID() 完全兼容和互操作
/// 2.简单、稳定、社区接受度高
/// 3.精度较低(约3.33毫秒)。
/// PS:建议使用此方案
/// </summary>
/// <returns></returns>
public static Guid NewComb()
{
byte[] guidArray = Guid.NewGuid().ToByteArray();
DateTime baseDate = new DateTime(1900, 1, 1);
DateTime now = DateTime.Now;
// 获取从基准时间到现在的毫秒数
TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
TimeSpan msecs = now.TimeOfDay;
// 转换为字节数组
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333));
// 反转字节顺序,因为 .NET 是小端序
if (BitConverter.IsLittleEndian)
{
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
}
// 将时间部分复制到 GUID 中
Buffer.BlockCopy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
Buffer.BlockCopy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
return new Guid(guidArray);
}
//使用 MassTransit 的有序 GUID
/// <summary>
/// NewId 转换为 GUID 可能不符合 RFC 4122 标准
/// 高性能要求:选择 MassTransit NewId
/// </summary>
/// <returns></returns>
public static Guid MassGenGuid()
{
return MassTransit.NewId.Next().ToGuid();
// 或者直接使用 NewId 类型
// Id = NewId.Next().ToString()
}
}