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导致事务日志空间 ...
随机推荐
- 第三章 Struts2配置详解
3.1 Struts2执行过程 1.获取Struts2资源 2.在应用程序中导入Struts2的类库 3.在web.xml中配置StrutsPrepareAndExecuteFilt ...
- 【Spark2.0源码学习】-1.概述
Spark作为当前主流的分布式计算框架,其高效性.通用性.易用性使其得到广泛的关注,本系列博客不会介绍其原理.安装与使用相关知识,将会从源码角度进行深度分析,理解其背后的设计精髓,以便后续 ...
- mvc中DotNetOpenAuth实现了第三方应用访问自己的网站
以yahoo为例吧,即从yahoo取得用户信息,存到自己的站点,实现了用户信息在一次录入多处共享的功能.以下是在点击了使用yahoo登录本站的链接后执行action:OpenId. ProviderU ...
- Tarjan-求强连通分量
知识点-Tarjan 强连通分量:在一个图的子图中,任意两个点相互可达,也就是存在互通的路径,那么这个子图就是强连通分量(或者称为强连通分支).如果一个有向图的任意两个点相互可达,那么这个图就称为强连 ...
- xLua中导出Dotween
前言 在xlua的lua脚本中使用dotween,官方的文档中有提到可以导出,但未介绍详细的步骤,相信比较多的朋友有需要,刚好项目中也在使用xlua和dotween,所以做个笔记. 基础知识: xLu ...
- 运行第一个Docker容器
1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...
- Oracle修改监听端口号1521[转]
在oracle中,默认的监听端口号为1521,一旦有人扫描出这个端口号就会知道此服务器为oracle数据库服务器,存在极其大的安全隐患,在这里,教大家如何修改oracle默认端口号为9999: 1.查 ...
- python基本运算
环境:python3.x a,b = 60,164 一.算数运算符 操作符 描述 例子 + 加法 a+b = 224 - 减法 a-b = -104 * 乘法 a*b = 9840 / 除(保留小数位 ...
- 最大流算法之EK(最短路径增广算法)
这是网络流最基础的部分--求出源点到汇点的最大流(Max-Flow). 最大流的算法有比较多,本次介绍的是其中复杂度较高,但是比较好写的EK算法.(不涉及分层,纯粹靠BFS找汇点及回溯找最小流量得到最 ...
- 详解Java动态代理机制(二)----cglib实现动态代理
上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我们动态生成的所有代理类都必须继承Proxy这个类, ...