高并发分布式系统中生成全局唯一(订单号)Id
1、GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么通过组合的方式,保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合起来,在保留GUID的唯一性的同时增加了有序性,以此来提高索引效率,在NHibernate中,COMB型主键的生成代码如下所示:
/// <summary> /// 保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime)组合方式 /// </summary> /// <returns></returns> public static Guid GenerateComb() { 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); }
上述方法循环测试生成id如下图
结论:适合大型应用。即保留GUID的唯一性的同时增加了GUID有序性,提高了索引效率;解决了关联表业务问题;生成的Id不够友好;占据了32位。
2、将GUID转为了19位数字
/// <summary> /// 根据GUID获取19位的唯一数字序列 /// </summary> public static long GuidToLong() { byte[] buffer = Guid.NewGuid().ToByteArray(); return BitConverter.ToInt64(buffer, 0); }
上述方法循环测试生成id如下图
结论:适合大型应用,从业务上来说,有一个规则的编码能体现产品的专业成度。