Floating point 使用datetime浮点表示法作为主键

Floating point 使用datetime浮点表示法作为主键,floating-point,primary-key,Floating Point,Primary Key,根据我的经验,我了解到使用代理INT数据类型列作为主键,特别是IDENTITY键列比使用GUID或char/varchar数据类型列作为主键提供更好的性能。 只要可能,我会尝试使用标识键作为主键。但最近我遇到了一个模式,其中表是水平分区的,并通过分区视图进行管理。因此表不能有标识列,因为这将使分区视图不可更新。解决这个问题的一个方法是创建一个带有标识列的虚拟“keygenerator”表,以生成主键的ID。但这意味着每个分区视图都有一个“keygenerator”表。 我的下一个想法是使用flo

根据我的经验,我了解到使用代理INT数据类型列作为主键,特别是IDENTITY键列比使用GUID或char/varchar数据类型列作为主键提供更好的性能。 只要可能,我会尝试使用标识键作为主键。但最近我遇到了一个模式,其中表是水平分区的,并通过分区视图进行管理。因此表不能有标识列,因为这将使分区视图不可更新。解决这个问题的一个方法是创建一个带有标识列的虚拟“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 
将浮点表示转换为完整的十进制值,即所有数字都被推到“.”的右侧

将整数形式的员工ID添加到此十进制值

其逻辑是,由于员工不能同时多次连接到应用程序,因此员工ID在会话中保证是唯一的。对于同一员工,每次生成密钥时,当前日期时间都是唯一的

在所有情况下,在所有员工会话和时间中使用唯一键

所以对于Emp id 11和12,我有一些键值,比如12.40046693321566357,11.40046693542361111


但我关心的是,与选择GUID或char/varchar作为主键相比,float数据类型作为主键是否有好处。同样重要的是,由于分区的浮点列将成为复合键的一部分。

< P>我不会考虑这样一个非正统的密钥生成模式-这有一个坏黑客的味道。你为什么不用整数呢?有许多方法和算法来协调分布式密钥生成。从锁定整个表并在每个客户端预先分配的id范围内搜索下一个可用id,到从特定于客户端的信息(类似于您的员工+时间建议)派生它。

既然您没有提到rdbms,我将使用SQL server。创建主键时,也会在该键上创建聚集索引。表格按此键的顺序排序。当使用guid作为主键(带有聚集索引)时,每次插入都意味着表的重新排序。这也适用于浮点表示。除此之外,如果希望使用此方案,请不要在此主键上创建聚集索引

同样重要的是,由于分区,浮点列将成为复合键的一部分

什么?为什么?为了使这个基于员工/时间的价值独一无二,您已经经历了巨大的痛苦,在主键中您还需要什么?在这个问题的另一方面,您的关键组件的其他组件是否已经是唯一的了?如果是这样,为什么不直接使用它们呢

你的计划让我很反感。但是我不太清楚为什么,因为我越想它,它看起来就越坚实

  • 一开始我担心表现。但是浮点值只有8个字节(假设您的DBMS使用IEEE 754 double),这并没有那么大。这并不比使用64位整数作为键或两个32位整数更糟糕。您的密钥生成过程是唯一可能会减慢的事情,但即使这样也不会太慢
  • 然后我开始担心独特性。此方案不能保证不会生成同一密钥两次。但是如果您断言user和datetime的组合是唯一的,那么这实际上可能会起作用:
    • IEEE 754 double具有53位精度
    • 日期时间将使用42位。假设:
      • datetime的分辨率为1/300秒(3.33…毫秒)。至少对于MS SQL Server来说是这样
      • 天花板(log2(86400*300*100000))=42
    • 这将为您的员工ID保留9位。如果员工ID大于511,则您将丢失部分日期时间,但它将以毫秒为单位。您的员工ID可以达到131071,否则您将失去超过一秒钟的准确性
  • 然后我担心以后查找键值的困难。考虑到0.2!=0.1+0.1的问题,浮点数相等的问题总是浮现在脑海中。但是没有理由对这个键值执行任何计算,并且假设它在任何给定时间都是IEEE 754 double格式(无论是在表中、在存储的过程变量中,还是在可执行文件的变量中),那么它永远不会更改,并且可以被视为唯一的64位值
在考虑了所有这些之后,您的方案看起来确实相对安全。关于不聚类索引是一个很好的方法,考虑到这一点,以及我上面关于员工ID大小的警告,您可以使用此方案生成主键,就像使用任何其他方法一样

不过,我仍然怀疑这是否是最好的方法,或者是否有必要

  • 复合密钥的其他组件是否可以自己使用(即,作为自然密钥)

  • 正如您所建议的,您可以在另一个表中保留一个顺序键种子。您只需要一个表,而不是像您假设的那样每个分区都需要一个表。这个表中只需要两列:一列用于分区号,另一列用于该分区的当前标识值

  • 使用GUID或varchar主键并非不可能。许多人在许多不同的桌子上这样做。这不会扼杀你的表演。它可能比这个方案更直接,或者至少更容易理解

  • 如果复合密钥已包含
    @KEY = @EMP_ID + @KEY