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导致事务日志空间 ...
随机推荐
- 浅谈C#抽象类
抽象类 先说个事,一个类实例化为一个实例.就是一只狗,实例化一下,就成了一只哈士奇(具体的二哈).但是,一个动物类实例化呐,成了啥? 压根就不能实例化.这,就是抽象类的概念引入. 概念:C#允许把类和 ...
- java复习(5)---接口、继承、多态
Java作为完全面向对象语言,接口.继承和多态是三个非常重要的概念. 1.继承. (1)关键字: extends (2)子类用super()调用父类构造函数,用super().方法 调用父类的成员方法 ...
- JavaScript分支语句if, else if, switch 案例详解
if语句主要是在需要判断,或者在可知有多少种情形时使用的语句.A==B?"A等于B";"A不等于B"; 基本结构: if(判断条件){ ...
- 交作业啊,python爬取58的页面
第一次写博文,好紧张啊,写这么烂怎么给别人看啊先做下总结: 刚开始学习python,自我感觉python写起来确实很方便,各种库,各种语法糖,不过刚接触,一下子记不下来这么多东西,总感觉乱乱的,用的多 ...
- c的旅程---字符
输出菱形实验: /***************** 2017年四月十六. 第一个例子,输出菱形.就是找关系. 这是当n= 3时, * *** * ******************/ #inclu ...
- seajs模块标识命名和解析规则
模块标识采用路径形式,但要注意与路径的区别.require.require.async的第一个参数是模块标识.而seajs.use第一个参数为文件路径. use是全局的,require是局部的.模块标 ...
- Java发布一个简单 webservice应用 并发送SOAP请求
一.创建并发布一个简单的webservice应用 1.webservice 代码: package com.ls.demo; import javax.jws.WebMethod; import ja ...
- 记录——时间轮定时器(lua 实现)
很长一段时间里,我错误的认识了定时器.无意中,我发现了“时间轮”这个名词,让我对定时器有了新的看法. 我错误的认为,定时器只需要一个 tick 队列,按指定的时间周期遍历队列,检查 tick 倒计时满 ...
- 初识Java反射
要详细的了解Java反射,就得要了解Java的类加载以及何为运行时动态加载等等概念.本文抛开其余概念,简单介绍Java反射,详细介绍会在以后有一个系统而全面的认识过后展开. 反射是Java被视为动态语 ...
- 【JAVAWEB学习笔记】25_基础加强:类加载器、注解 @xxx和动态代理
基础加强 学习目标 案例-自定义单元测试@MyTest 案例-全局的编码的解决 一.类加载器 1.什么是类加载器,作用是什么? 类加载器就加载字节码文件(.class) 2.类加载器的种类 类加载器有 ...