使用日期时间浮点表示作为主键(Using datetime float representation

2019-10-17 09:14发布

从我的经验我也了解到,使用替代INT数据类型的列作为主键ESP。 一个IDENTITY键列提供了比使用GUID或字符/ varchar数据类型列作为主键更好的性能。 我尝试尽可能使用IDENTITY键作为主键。 但最近我碰到其中表被水平分区,并通过分区视图进行管理的模式。 因此,表不能有一个IDENTITY列,因为这会使分区视图不可更新。 一个解决这个是创建标识列虚设“的KeyGenerator”表生成主键的ID。 但是,这将意味着有每个分区视图的“的KeyGenerator”表。 我的下一个念头,就是使用float作为主键。 其原因是,我设计了以下关键算法

DECLARE @KEY FLOAT

SET @KEY = CONVERT(FLOAT,GETDATE())/100000.0 

SET @KEY = @EMP_ID + @KEY

Heres how it works.

CONVERT(FLOAT,GETDATE()) 

给出,因为内部的所有的日期时间是由SQL作为浮点值来表示当前日期时间的浮点表示。

CONVERT(FLOAT,GETDATE())/100000.0 

转换浮子表示成完整的十进制值即所有数字都推到右侧“”。

@KEY = @EMP_ID + @KEY

增加了雇员ID这是此十进制值的整数。

的逻辑是,雇员ID保证是跨会话独一无二的,因为雇员不能连接到一个应用程序不止一次在同一时间。 而每一次为同一雇员的一个键会生成当前日期时间将是独一无二的。

在所有员工会议,并在时间上所有的唯一键。

因此,有关EMP IDS 11和12,我有键值像12.40046693321566357,11.40046693542361111

但我关心的float数据类型作为主键报价收益是否比选择GUID或字符/ VARCHAR作为主键。 同样重要的是,因为分区浮法列将会是一个复合键的一部分。

Answer 1:

同样重要的是,因为分区浮法列将会是一个复合键的一部分。

什么? 为什么? 你已经通过不厌其烦的尝试,使这个员工/基于时间的独特价值了,否则你会在主键中需要什么? 而对这个问题的另一面,是你唯一的密钥的其他组件了吗? 如果是这样,为什么不使用他们?

你的计划离开我口不好的味道。 我不明白为什么,虽然,因为,我越去想它,更坚实,似乎。

  • 起初我担心性能。 但浮动仅有8个字节(假设你的DBMS使用IEEE 754双),这仅仅是不是所有的大。 这是没有比具有64位整数作为键,或两个32位整数差。 你的密钥生成过程是可能由多减慢,但即使不是唯一的东西。
  • 然后,我担心唯一性。 该方案并不能保证你不会产生相同的键两次。 但考虑到你的说法,用户和日期时间的结合将是唯一的,那么这可能实际工作:
    • IEEE 754双具有精度53位。
    • 日期时间将使用42位。 假设:
      • 日期时间的分辨率为1/300秒(3.33 ...毫秒)。 这适用于MS SQL Server中,至少。
      • 天花板(日志2(86400 * 300 * 100000))= 42
    • 这使得你的员工ID 9位。 如果员工ID量大于511,那么你将失去的日期时间的一部分,但它会毫秒的量级。 你的员工ID可以达到131071之前,你将失去超过一秒的精确度。
  • 然后,我担心在以后的查找键值的难度。 鉴于0.2!= 0.1 + 0.1的问题,浮点平等的关注总是浮现在脑海中。 但是,没有任何原因,你会在这个关键值进行任何计算,想必这将是IEEE在任何给定时间754双格式(不论是在该表中,存储过程变量,或者在你的可执行文件的变量),然后它应该永远不会改变,并且可以被视为一个唯一的64位值。

考虑到这毕竟,你的方案确实出现比较安全。 Edoode的建议,关于不聚类索引是一个很好的,并考虑到这一点,以及我的警告以上有关你的员工ID的大小,您可以使用此方案来产生只是主键以及任何其他方法。

我仍然质疑它是否是最好的方法,但是,或者如果它甚至是必要的。

  • 可在复合键的其他组件无法单独使用(即,作为天然的键)?

  • 可以 ,你的建议,保留另一个表中的顺序密钥种子。 而当你认为你只需要一个表,而不是每个分区一个表。 你只需要两列在此表中:一个分区号,以及一个用于该分区的当前标识值。

  • 使用GUID或varchar的主键是不是出了问题。 很多人做这在许多不同的表。 它不会杀死你的表现。 它可能是更直接的,或者至少更容易理解,比这个方案。

  • 如果你的组合键已包括雇员ID,只需要添加日期时间列键和收工。 或者,如果没有,你可以添加两个列。 没有理由,你必须混搭两者结合起来。

HTH



Answer 2:

我不会考虑这样一种非正统的密钥生成模式 - 这有一个坏的黑客的滋味。 你为什么不只是使用整数? 有许多方法和算法来协调分布式密钥生成。 从锁定整个表(S)和超过预分配每个客户ID的范围从客户获得它的具体信息(类似于你的员工+时间建议)寻找下一个空闲的ID。



Answer 3:

既然你没有提到的RDBMS我asume SQL服务器。 当创建一个主键,也创造了该键的聚簇索引。 一个表在这个关键的顺序进行排序。 当使用的GUID作为主键(与群集索引)每个插入意味着表的重新排序。 这也适用于您的浮点表示真实。 其他问题不谈,如果你想使用这个方案,就无法创建该主键聚集索引。



文章来源: Using datetime float representation as primary key