C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)
GUID作为数据库主键由于其无序性所以性能不怎么好,SQL Server中有个函数NewSequentialId可以生成有序的GUID,由于在程序中需要用到,就用C#实现了一下,生成的GUID格式基本和SQL Server一致。
程序代码参考了rpcrt4.dll中UuidCreateSequential的实现。
public class GuidHelper
{
private static bool initialised;
private static int count; private static long time;
private static long timelast;
private static ushort sequence; private static byte[] address; //网卡MAC
private static readonly object locker = new object();
public static Guid NewSequentialId()
{
lock(locker)
{
if (!initialised)
{
timelast = UuidGetSystemTime();
count = TICKS_PER_CLOCK_TICK;
Random rand = new Random();
sequence = (ushort)(((rand.Next(, ) & 0xFF) << ) + rand.Next(, ) & 0xFF);
sequence &= 0x1FFF;
address = GetAddressBytes();
initialised = true;
}
while (true)
{
time = UuidGetSystemTime();
if (time > timelast)
{
count = ;
break;
}
if (time < timelast)
{
sequence = (ushort)((sequence + ) & 0x1FFF);
count = ;
break;
}
if (count < TICKS_PER_CLOCK_TICK)
{
count++;
break;
}
} timelast = time;
time += count; byte[] guidArray = new byte[]; uint data1 = (uint)(time & 0xffffffff);
ushort data2 = (ushort)((time >> ) & 0xffff);
ushort data3 = (ushort)((time >> ) & 0x0fff);
/* This is a version 1 UUID */
data3 |= ( << ); guidArray[] = (byte)data1;
guidArray[] = (byte)(data1 >> );
guidArray[] = (byte)(data1 >> );
guidArray[] = (byte)(data1 >> );
guidArray[] = (byte)data2;
guidArray[] = (byte)(data2 >> );
guidArray[] = (byte)data3;
guidArray[] = (byte)(data3 >> );
guidArray[] = (byte)(sequence & 0xff);
guidArray[] = (byte)((sequence & 0x3f00) >> );
guidArray[] |= 0x80;
Array.Copy(address, , guidArray, , ); return new Guid(guidArray);
}//locker
}//UuidCreateSequential private static readonly int TICKS_PER_CLOCK_TICK = ;
private static readonly int SECSPERDAY = ;
private static readonly int TICKSPERSEC = ;
private static readonly long SECS_15_OCT_1582_TO_1601 = ( + + + * + ) * SECSPERDAY;
private static readonly long TICKS_15_OCT_1582_TO_1601 = SECS_15_OCT_1582_TO_1601 * TICKSPERSEC;
private static long UuidGetSystemTime()
{
DateTime dt = DateTime.Now;
var ft = dt.ToFileTime();
ft += TICKS_15_OCT_1582_TO_1601;
return ft;
} private static byte[] GetAddressBytes()
{
byte[] bytes;
NetworkInterface[] nic = NetworkInterface.GetAllNetworkInterfaces();
if (nic == null || nic.Length < )
{
bytes = new byte[];
bytes[] = 0x01;
return bytes;
}
bytes = nic[].GetPhysicalAddress().GetAddressBytes();
return bytes;
}
}
代码写的比较粗糙,不过功能已经实现,有需要的朋友可以自行优化!
C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)的更多相关文章
- 针对多类型数据库,集群数据库的有序GUID
一.背景 常见的一种数据库设计是使用连续的整数为做主键,当新的数据插入到数据库时,由数据库自动生成.但这种设计不一定适合所有场景. 随着越来越多的使用Nhibernate.EntityFramewor ...
- 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor
批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor2.1.11 之前写过一篇文章,使用redgate公司的SQL PROMPT工具,但是不太方便 SQLPRO ...
- PowerDesigner从SqlServer数据库中导入实体模型
PowerDesigner从SqlServer数据库中导入实体模型 时间 2013-06-28 10:26:34 CSDN博客 原文 http://blog.csdn.net/sxycxwb/art ...
- 获取sqlserver数据库中所有库、表、字段名的方法
获取sqlserver数据库中所有库.表.字段名的方法 2009年03月12日 星期四 下午 12:51 1.获取所有数据库名: SELECT Name FROM Master..SysDatabas ...
- 设置SQLServer数据库中某些表为只读的多种方法
原文:设置SQLServer数据库中某些表为只读的多种方法 翻译自:http://www.mssqltips.com/sqlservertip/2711/different-ways-to-make- ...
- 【转载】Sqlserver数据库中无自增Id的情况下使用ROW_NUMBER()函数进行数据分页
在Sqlserver数据库中,如果查询表中含有自增长Id列,一般会采用select Top的方式来数据的分页操作.而实际上很多数据表设计的时候,不一定含有自增长Id列,那么数据库没有Id自增列的时候要 ...
- Sqlserver数据库中的临时表详解
临时表在Sqlserver数据库中,是非常重要的,下面就详细介绍SQL数据库中临时表的特点及其使用,仅供参考. 临时表与永久表相似,但临时表存储在tempdb中,当不再使用时会自动删除.临时表有两种类 ...
- 关于在Java中链接SQLServer数据库中失败的原因分析
首先声明:笔者是Java的初学者,并且一值是走在自学的道路上,长久以来只有“度娘”相伴.(加入了各种Java学习群,基本没有热心帮人解决问题的.可以理解-_-!!!)大神级的人物就不必看拙文了,没有什 ...
- SQLServer数据库中开启CDC导致事务日志空间被占满的原因
SQLServer数据库中开启CDC导致事务日志空间被占满的原因 转载 2017-04-01 投稿:mrr 我要评论 这篇文章主要介绍了SQLServer数据库中开启CDC导致事务日志空间 ...
随机推荐
- jmeter执行case结果插入DB数据优化
访问初始实现路径:jmeter执行case结果插入DB生成报表和备份记录 借前面实现导入DB数据先说明之前数据的缺点: 第一,若需要依赖接口的数据,会把依赖接口的case统计进去造成数据统计错误.第二 ...
- 更改oracle字符集
修改oracle字符集 方法/步骤 oracle数据库的字符集更改 A.oracle server 端 字符集查询 select userenv('language') from dual 其中 ...
- Excel 中使用sql语句查询
将Excel连接Oracle数据库 Excel选项板中"数据"—"自其他来源"下拉菜单中有有个可以连接其它数据库的选项"来自数据连接向导"和 ...
- API 管理工具
API 管理工具 你还苦于无法有效的管理大量的API吗?今天给大家介绍一款API的管理工具.这款工具可以免费使用,虽然中途可能会提示你购买,但并不影响我们的使用. 下载地址: Windows:http ...
- CentOS 7安装Docker
在虚拟机CentOS 7上安装Docker ## 零:检查前提条件: 在Red Hat 和Red Hat系列的Linux发行版中,安装Docker所需的前提提交并不多. ### 1.内 ...
- Spark机器学习之协同过滤算法
Spark机器学习之协同过滤算法 一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相 ...
- 关于在"a"标签中添加点击事件的一些问题
昨天做修改页面跳转时遇到一个问题,如果a标签的"href"属性为空的话,比如这样<a href="" onclick="roleupdate() ...
- trait技术详解,这次包你学得会
trait的使用技巧trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类,就像是装配汽车的配件,如果你的类中要用到这些配件,就直接用use导入 ...
- OC中的单例
概念 单例模式的意图是类的对象称为系统中唯一的实例,提供一个访问点,供客户类共享资源 什么情况下使用单例 )类只能由一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法 )这个唯一的实例 ...
- 【持续集成】GIT+jenkins+snoar——GIT
一.GIT基础 1.1 git简介 linux用C语言编写 2005年诞生 分布式管理系统 速度快.适合大规模.跨地区多人协同开发 1.2 本地管理.集中式.分布式 1.3 git安装 #CentOS ...