C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)

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     }

代码写的比较粗糙,不过功能已经实现,有需要的朋友可以自行优化!

时间: 2024-11-05 13:43:01

C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)的相关文章

批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor

原文:批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor2.1.11 之前写过一篇文章,使用redgate公司的SQL PROMPT工具,但是不太方便 SQLPROMPT5.3对各种加密对象的解密测试 SQL2005解密已经被加密的存储过程 昨天ahdung 童鞋介绍了这个工具给我,非常感谢他 dbForge SQL Decryptor这个工具的软件公司是dev

sqlserver 数据库中时间函数的建立

create function [dbo].[HtoSec](@lvalue as int)RETURNS intBEGINDECLARE @temp intSet @temp = @lvalue * 60 * 60RETURN @tempEND create function [dbo].[GetTime](@dtmValue as datetime)RETURNS intBEGINDECLARE @temp intDECLARE @GMT_TIMEZONE intSET @GMT_TIMEZ

获取sqlserver数据库中所有库、表、字段名的方法

1.获取所有数据库名: SELECT Name from Master..SysDatabases ORDER BY Name 2.获取所有表名: SELECT Name from DatabaseName..SysObjects Where XType='U' ORDER BY Name XType='U':表示所有用户表; XType='S':表示所有系统表; 3.获取所有字段名: SELECT Name from SysColumns WHERE id=Object_Id('TableNa

SQLServer数据库中了勒索病毒,MDF文件扩展名被篡改了。

如果您的服务器中了勒索病毒,扩展名被篡改了.SQLServer数据库中了勒索病毒,MDF文件扩展名被篡改了.解密联系:QQ 80554803 TEL: 18620906802(微信) 如果您的文件被如下勒索病毒加密:? Trojan-Ransom.Win32.Rakhni? Trojan-Ransom.Win32.Agent.iih? Trojan-Ransom.Win32.Autoit? Trojan-Ransom.Win32.Aura? Trojan-Ransom.AndroidOS.Ple

Sqlserver数据库中,跨权限执行语句

原文:Sqlserver数据库中,跨权限执行语句 问题来源:最近有同事需要执行批量删除语句.根据他提供的业务需求,推荐他使用"TRUNCATE TABLE"语句.但使用该语句需要 ALTER权限,这与执行用户的角色不符. 解决办法:使用EXECUTE AS语句修改执行权限.代码如下: ALTER PROCEDURE [dbo].[sp_TruncateTable] @TableName varchar(200) WITH EXECUTE AS SELF AS BEGIN --打印出当前

在Oracle数据库中实现SqlServer数据库中的NewID()函数功能

因为我是使用.NET C#进行开发,所以平时会使用SqlServer的NewID()函数来生成数据的ID. 在C#语言中也可以很方便地使用Guid.NewGuid().ToString()方法来生成格式一样的ID. 现在数据库换成了Oracle,没有类似的函数可以方便地调用,但是Oracle中自带一个函数SYS_GUID(). 返回的是一串二进制的数据,可以通过CAST转换成VARCHAR类型后就是类似SqlServer中NewID()方法生成的ID的样子了. 我们只要再做下手脚,往里面插入几个

使用java获取网页内容并存放在SqlServer数据库中

同学突然有个蛋疼的需求,抓取以下界面的数据至数据库,我因为很闲,更加蛋疼的自告奋勇帮忙完成.http://www.shmet.com/Template/_Template.html?viewName=_HomeSpotPrice&metalid=10133%2C10131%2C10132%2C10002%2C10003%2C10134%2C10135&_=1453249939502 主要分为3部分: 1)从网页获取数据. 2)将获取的数据实体list集合中去. 3)存入数据库中. 从网页获

Excel中的数据导入到SqlServer数据库中

从SqlServer2008才开始支持导出表结构的和表中的数据,而SqlServer2008以前的数据库只支持导出表结构,有些时候我们可能需要把2008以前的数据库中的数据导出来,这个时候我们可以使用折中的方法,先把数据库导出到Excel中,再把Excel中的数据导入到数据库中(如果两台数据库服务器之间可以互通的话,可以直接建立远程链接进行数据传输,不用如此麻烦), 将SqlServer中的数据导出到Excel中比较简单,这里不再贴图,下面是把Excel中的数据导入到SqlServer中步骤:

Java将图片资源以二进制的形式保存到Sqlserver数据库中

如何使用Java语言将图片资源以二进制的形式保存的数据库中 在sqlserver中创建表 use MyDb1go create table SaveImg(id varchar(10) primary key,img image not null) select *from SaveImg 使用微软提供的sqljdbc4.jar进行数据库存储,开始我使用的是jtds发现存储不了,然后才使用的sqljdbc,这个我没有细究,有兴趣的可以试试. Java的demo package com.ht.sa