摘要:本文主要向大家介绍了SQLServer数据库之C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId),通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助。
本文主要向大家介绍了SQLServer数据库之C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId),通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助。
GUID作为数据库主键由于其无序性所以性能不怎么好,SQL Server中有个函数NewSequentialId可以生成有序的GUID,由于在程序中需要用到,就用C#实现了一下,生成的GUID格式基本和SQL Server一致。
程序代码参考了rpcrt4.dll中UuidCreateSequential的实现。
1 public class GuidHelper
2 {
3 private static bool initialised;
4 private static int count;
5
6 private static long time;
7 private static long timelast;
8 private static ushort sequence;
9
10 private static byte[] address; //网卡MAC
11 private static readonly object locker = new object();
12 public static Guid NewSequentialId()
13 {
14 lock(locker)
15 {
16 if (!initialised)
17 {
18 timelast = UuidGetSystemTime();
19 count = TICKS_PER_CLOCK_TICK;
20 Random rand = new Random(1);
21 sequence = (ushort)(((rand.Next(1, 32767) & 0xFF) << 8) + rand.Next(1, 32767) & 0xFF);
22 sequence &= 0x1FFF;
23 address = GetAddressBytes();
24 initialised = true;
25 }
26 while (true)
27 {
28 time = UuidGetSystemTime();
29 if (time > timelast)
30 {
31 count = 0;
32 break;
33 }
34 if (time < timelast)
35 {
36 sequence = (ushort)((sequence + 1) & 0x1FFF);
37 count = 0;
38 break;
39 }
40 if (count < TICKS_PER_CLOCK_TICK)
41 {
42 count++;
43 break;
44 }
45 }
46
47 timelast = time;
48 time += count;
49
50 byte[] guidArray = new byte[16];
51
52 uint data1 = (uint)(time & 0xffffffff);
53 ushort data2 = (ushort)((time >> 32) & 0xffff);
54 ushort data3 = (ushort)((time >> 48) & 0x0fff);
55 /* This is a version 1 UUID */
56 data3 |= (1 << 12);
57
58 guidArray[3] = (byte)data1;
59 guidArray[2] = (byte)(data1 >> 8);
60 guidArray[1] = (byte)(data1 >> 16);
61 guidArray[0] = (byte)(data1 >> 24);
62 guidArray[5] = (byte)data2;
63 guidArray[4] = (byte)(data2 >> 8);
64 guidArray[7] = (byte)data3;
65 guidArray[6] = (byte)(data3 >> 8);
66 guidArray[8] = (byte)(sequence & 0xff);
67 guidArray[9] = (byte)((sequence & 0x3f00) >> 8);
68 guidArray[9] |= 0x80;
69 Array.Copy(address, 0, guidArray, 10, 6);
70
71 return new Guid(guidArray);
72 }//locker
73 }//UuidCreateSequential
74
75 private static readonly int TICKS_PER_CLOCK_TICK = 1000;
76 private static readonly int SECSPERDAY = 86400;
77 private static readonly int TICKSPERSEC = 10000000;
78 private static readonly long SECS_15_OCT_1582_TO_1601 = (17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY;
79 private static readonly long TICKS_15_OCT_1582_TO_1601 = SECS_15_OCT_1582_TO_1601 * TICKSPERSEC;
80 private static long UuidGetSystemTime()
81 {
82 DateTime dt = DateTime.Now;
83 var ft = dt.ToFileTime();
84 ft += TICKS_15_OCT_1582_TO_1601;
85 return ft;
86 }
87
88 private static byte[] GetAddressBytes()
89 {
90 byte[] bytes;
91 NetworkInterface[] nic = NetworkInterface.GetAllNetworkInterfaces();
92 if (nic == null || nic.Length < 1)
93 {
94 bytes = new byte[6];
95 bytes[0] = 0x01;
96 return bytes;
97 }
98 bytes = nic[0].GetPhysicalAddress().GetAddressBytes();
99 return bytes;
100 }
101 }
代码写的比较粗糙,不过功能已经实现,有需要的朋友可以自行优化
本文由职坐标整理并发布,希望对同学们学习SQL Server有所帮助,更多内容请关注职坐标数据库SQL Server数据库频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号