在项目中我需要使用到一个随机数(Random Number),该随机数将作为 Hashtable 中的 Key 用于唯一索引数据,所以需要保持单机唯一性。

同时该随机数还需要具备可排序性以便对数据进行排序。

此时,我可以考虑使用随机字符串《C#生成MongoDB中的ObjectId》,这里的 ObjectId 具备单机唯一性和可排序性。

但另一个需求是,我需要该随机数为 int 或 long 类型,以便与依赖的 Service 进行通信,部分取代 TransactionId 或 Token 的职责。

所以,很自然的我就想到了时间。

查看了 MSDN 上关于 DateTime.MinValueDateTime.Ticks 的定义,考虑到我所设计的服务每秒不会产生多于 10000000 的数据,

我决定使用 DateTime.Ticks 作为随机数的起始点,这样就有了下面这段代码。

  1. public static class UniqueId
  2. {
  3. private static long _sequence = DateTime.UtcNow.Ticks;
  4.  
  5. public static long Generate()
  6. {
  7. return Interlocked.Increment(ref _sequence);
  8. }
  9.  
  10. public static long Sequence
  11. {
  12. get
  13. {
  14. return _sequence;
  15. }
  16. }
  17. }

业务逻辑中会将 UniqueId 存储到 SQL Server 数据库中,使用 bigint 类型进行存储。

  1. CREATE TABLE [TableName](
  2. [UniqueId] [bigint] NOT NULL,
  3. );

这样,在数据库中,该 UniqueId 即可作为索引,也可进行排序。

现在问题来了,我需要将一个较老的服务升级到新的服务中,做 Date Migration。

老的服务中没有 UniqueId 逻辑和数据,这就需要我在数据迁移时为每条表数据生成该 UniqueId。

显然,SQL Server 不会帮我做这件事,我需要使用 SQL Script 来生成 UniqueId。

DateTime.Ticks 的定义是:

A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.

1 Tick 等于千万分之一秒,或万分之一毫秒。

The value represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001, which represents DateTime.MinValue.

DateTime.Ticks 代表着从时间 "00:00:00.0000000, January 1, 0001" 至当前时间的 Tick 总数。

这样,我们就可以根据其原理通过 SQL 来计算其值。

  1. DECLARE @current_datetime DATETIME;
  2. DECLARE @days_from_0001_to_1900 BIGINT;
  3. DECLARE @ticks_per_millisecond BIGINT;
  4. DECLARE @ticks_per_day BIGINT;
  5. DECLARE @millisecond_of_time BIGINT;
  6. DECLARE @ticks_of_days BIGINT;
  7. DECLARE @ticks_of_time BIGINT;
  8. DECLARE @ticks BIGINT;
  9.  
  10. SET @current_datetime = GETUTCDATE();
  11. SET @days_from_0001_to_1900 = 693595;
  12. SET @ticks_per_millisecond = 10000;
  13. SET @ticks_per_day = 24 * 3600 * 1000 * @ticks_per_millisecond;
  14. SET @millisecond_of_time =
  15. DATEPART(MILLISECOND, @current_datetime)
  16. + (DATEPART(SECOND, @current_datetime)) * 1000
  17. + (DATEPART(MINUTE, @current_datetime)) * 60000
  18. + (DATEPART(HOUR, @current_datetime)) * 3600000;
  19. SET @ticks_of_days = CAST(@days_from_0001_to_1900 + DATEDIFF(DAY, 0, @current_datetime) AS BIGINT) * @ticks_per_day;
  20. SET @ticks_of_time = @millisecond_of_time * @ticks_per_millisecond;
  21. SET @ticks = @ticks_of_days + @ticks_of_time;
  22.  
  23. SELECT @current_datetime, @ticks

这段 SQL 脚本的运行结果是:

我们通过下面这段 C# 代码来验证结果。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. DateTime d1 = new DateTime(, , , , , , , DateTimeKind.Utc);
  6. DateTime d2 = DateTime.Parse("2014-04-01 02:52:54.153");
  7. DateTime d3 = DateTime.Parse("2014-04-01 02:52:54.153",
  8. CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal);
  9.  
  10. Console.WriteLine(d1.Ticks);
  11. Console.WriteLine(d2.Ticks);
  12. Console.WriteLine(d3.Ticks);
  13.  
  14. Console.ReadKey();
  15. }
  16. }

瞧,它们的结果一致为 635319175741530000。

使用SQL生成DateTime.Ticks的更多相关文章

  1. 重构 ORM 中的 Sql 生成

    Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成   前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 OR ...

  2. C#中DateTime.Ticks属性及Unix时间戳转换

    1.相关概念 DateTime.Ticks:表示0001 年 1 月 1 日午夜 12:00:00 以来所经历的 100 纳秒数,即Ticks的属性为100纳秒(1Ticks = 0.0001毫秒). ...

  3. 【转】一道SQL SERVER DateTime的试题

    学习过上一篇SQL SERVER DateTime精度的文章后.再来做一道题. IF ('2011-07-31 00:00:00.000' BETWEEN '2011-07-01' and '2011 ...

  4. c#保存datagridview中的数据时报错 “动态SQL生成失败。找不到关键信息”

    ilovejinglei 原文 C#中保存datagridview中的数据时报错"动态SQL生成失败.找不到关键信息" 问题描述     相关代码 using System; us ...

  5. LINQ To SQL 处理 DateTime?

    LINQ To SQL 处理 DateTime? 类型 例子: 搜索栏含有最后扫描时间的日期(DateTime?)与多个其他条件(String) 现在需要写一个查询 : 查询符合最后扫描的日期的查询 ...

  6. 一条SQL生成数据字典

    有个字典表并定期维护,对DBA和开发很重要,终于把他们整合在一起了,看有没问题? 一条SQL生成数据字典,包含所有OPEN用户.表名.字段名.字段序号.字段属性.默认值.是否非空.字段意思.主键标识. ...

  7. 对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成

    大家知道,DataSet保存的数据是位于服务器内存里面的原数据库的“副本”.所以用DataSet更新数据的过程就是先对“副本”进行更新,然后 在将“原本”更新,按照我的理解就是把“原本”覆盖掉.具体到 ...

  8. 查看Linq to Sql生成的sql语句(转)

    查看Linq to Sql生成的sql语句   在控制台项目中,比较简单,直接db.Log = Console.Out;就OK了 但是在其他项目中,需要处理如下: StreamWriter sw = ...

  9. SQL中DateTime转换成Varchar样式

    SQL中DateTime转换成Varchar样式语句及查询结果:Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect ...

随机推荐

  1. iOS判断数组不为空

    用([array count]==0 )来判断是否为空,都是坑,如果array为空的话,执行count就会直接报错,程序崩溃退出. 正确判断NSArray是否为空的方法: if(array != ni ...

  2. Httpoxy远程代理感染漏洞 [转]

    Httpoxy是一个最新曝出的一个CGI程序漏洞,它主要可能威胁到运行在CGI上的PHP,Go,Python和其他代码程序语言. 0×01  什么是httpoxy? 具体来说, httpoxy是一组影 ...

  3. 深入浅出UML类图(一)

    在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML Distilled: A Brief Guide to the Standard O ...

  4. ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法

    ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块  --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...

  5. UI线程和work线程

    UI线程处理消息,比如重绘,响应键盘鼠标等等跟消息有关的处理. 而工作线程一般是你自己写的用来处理数据的,比如操作数据库等等.(work线程)    

  6. JS-concat

    var arr1 = [ 1,2,3 ];var arr2 = [ 4,5,6 ];var arr3 = [ 7,8,9 ];alert( arr1.concat( arr2, arr3 ) );

  7. 用词法分析器Flex过滤日志

    每日构造中,我的项目中 Visual Studio 的 MakeFile 后会产生大量信息,如下 Microsoft (R) Visual Studio Version 10.0.40219.1.Co ...

  8. 领域模型驱动设计(Domain Driven Design)入门概述

    软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 ...

  9. [UE4]自定义MovementComponent组件

    自定义Movement组件 目的:实现自定义轨迹如抛物线,线性,定点等运动方式,作为组件控制绑定对象的运动. 基类:UMovementComponent 过程: 1.创建UCustomMovement ...

  10. Linux之DNS

    DNS服务器配置 一.DNS概述:DNS 是域名系统 (Domain Name System) 的缩写,是一种组织域层次结构的计算机和网络服务命名系统.它的作用是:把域名转换成为网络可以识别的 IP ...