高并发分布式系统中生成全局唯一(订单号)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如下图

结论:适合大型应用,从业务上来说,有一个规则的编码能体现产品的专业成度。

猜你喜欢

转载自www.cnblogs.com/linJie1930906722/p/9547749.html