收集几种生成顺序GUID的方法

来源:互联网 发布:数据融合关键技术 编辑:程序博客网 时间:2024/06/09 13:50

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
15c44698-4b52-c379-04d1-08d07e5fad6c
a4abcb36-71e9-c2a2-04d1-08d07e5fad6c
bb03c46a-ab7a-ca27-04d1-08d07e5fad6c
e4b7b99e-2a8f-cb0a-04d1-08d07e5fad6c
26ac7070-3294-ca22-04d1-08d07e5fad6c
423a83c7-633a-c98c-04d1-08d07e5fad6c
f2480bdb-2260-c112-04d1-08d07e5fad6c
3b76a6dc-8534-cd29-04d1-08d07e5fad6c
e12fbfe7-dc1f-c57b-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);
View Code

 最终代码变为:

复制代码
        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();        }