收集几种生成顺序GUID的方法
public static class Generator { [DllImport("rpcrt4.dll", SetLastError = true)] public static extern int UuidCreateSequential(out Guid guid); private const int RPC_S_OK = 0; public static Guid CreateRpcrt4Guid() { Guid guid; int result = UuidCreateSequential(out guid); if (result == RPC_S_OK) return guid; else return Guid.NewGuid(); } public static Guid CreateSecuentialGuid() { byte[] uid = Guid.NewGuid().ToByteArray(); byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks); byte[] secuentialGuid = new byte[uid.Length]; secuentialGuid[0] = uid[0]; secuentialGuid[1] = uid[1]; secuentialGuid[2] = uid[2]; secuentialGuid[3] = uid[3]; secuentialGuid[4] = uid[4]; secuentialGuid[5] = uid[5]; secuentialGuid[6] = uid[6]; // set the first part of the 8th byte to '1100' so // later we'll be able to validate it was generated by us secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7])); // the last 8 bytes are sequential, // it minimizes index fragmentation // to a degree as long as there are not a large // number of Secuential-Guids generated per millisecond secuentialGuid[9] = binDate[0]; secuentialGuid[8] = binDate[1]; secuentialGuid[15] = binDate[2]; secuentialGuid[14] = binDate[3]; secuentialGuid[13] = binDate[4]; secuentialGuid[12] = binDate[5]; secuentialGuid[11] = binDate[6]; secuentialGuid[10] = binDate[7]; return new Guid(secuentialGuid); } public static Guid CreateCombGuid() { byte[] guidArray = Guid.NewGuid().ToByteArray(); 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; // 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); } }
每种方法只生成10条记录,结果如下
| rpcrt4: | Secuential: | Comb: |
| f8373adb-cf34-11e2-be8d-d43d7e333b2c f8373adc-cf34-11e2-be8d-d43d7e333b2c f8373add-cf34-11e2-be8d-d43d7e333b2c f8373ade-cf34-11e2-be8d-d43d7e333b2c f8373adf-cf34-11e2-be8d-d43d7e333b2c f8373ae0-cf34-11e2-be8d-d43d7e333b2c f8373ae1-cf34-11e2-be8d-d43d7e333b2c f8373ae2-cf34-11e2-be8d-d43d7e333b2c f8373ae3-cf34-11e2-be8d-d43d7e333b2c f8373ae4-cf34-11e2-be8d-d43d7e333b2c |
e8edcc23-9c22-c3b1-04d1-08d07e5fad6c |
65d8b46f-ea29-41f8-af76-a1d600e29f85 2c95c4c2-aca4-46de-b842-a1d600e29f85 c6f054ea-dbb4-432c-aed3-a1d600e29f85 2b47c23c-ac18-467c-8c2d-a1d600e29f85 4dbe1536-ccb1-4fc4-b145-a1d600e29f85 cccd4c08-6c52-4b12-90fc-a1d600e29f85 f6f07bde-5108-43c0-9294-a1d600e29f85 921a018f-9545-447b-8c99-a1d600e29f85 fbc560a3-acbe-48da-9b06-a1d600e29f85 bbfbbe7f-2bc6-4bd7-bbae-a1d600e29f85 |
单从结果上看,第一种使用起来更方便些.
但这种方法有一个问题,就是在SQL SERVER中排序还是会乱,所以在需要排序的时候,需要对这种生成方式进行简单处理,增加一点代码
byte[] guidBytes = guid.ToByteArray(); Array.Reverse(guidBytes, 0, 4); Array.Reverse(guidBytes, 4, 2); Array.Reverse(guidBytes, 6, 2);
最终代码变为:
public static Guid CreateRpcrt4Guid() { Guid guid; int result = UuidCreateSequential(out guid); if (result == RPC_S_OK) { byte[] guidBytes = guid.ToByteArray(); Array.Reverse(guidBytes, 0, 4); Array.Reverse(guidBytes, 4, 2); Array.Reverse(guidBytes, 6, 2); return new Guid(guidBytes); } else return Guid.NewGuid(); }
浙公网安备 33010602011771号