【问题标题】:Locally unique identifier本地唯一标识符
【发布时间】:2010-08-14 22:29:17
【问题描述】:

问题:当你有一个用于插入数据库的 .NET GUID 时,它的结构是这样的:

60 bits of timestamp, 
48 bits of computer identifier,
14 bits of uniquifier, and
 6 bits are fixed, 
----
128 bits total

现在我遇到了 GUID 的问题,因为它是一个 128 位数字,而我使用的一些 DB 仅支持 64 位数字。

现在我不想通过使用自动增量 bigint 值来解决这个难题,因为我希望能够进行离线复制。

所以我产生了创建一个本地唯一标识符类的想法,它基本上是一个缩小为 64 位值的 GUID。

我想出了这个:

day  9 bit (12*31=372 d)
year 8 bit (2266-2010 = 256 y)
seconds  17 bit (24*60*60=86400 s)
hostname 12 bit (2^12=4096)
random 18 bit (2^18=262144)
------------------------
          64 bits total

我现在的问题是:时间戳几乎固定为 34 位,主机名 + 随机数留给我 64-34=30 位。

现在我的问题是: 1)您是希望增加hostname-hash bitsize而减少random bitsize,还是增加random bitsize而减少hostname-hash bitsize。

2) 是否存在将每个字符串减少到 n 位的哈希算法? n 理想情况下 = 12 或尽可能接近。

【问题讨论】:

    标签: c# .net vb.net guid uniqueidentifier


    【解决方案1】:

    实际上,.NET 生成的 GUID 是 6 个固定位和 122 个随机位。

    您可以考虑只使用 64 位的随机性,由于位长度较小,冲突的可能性会增加。它会比哈希更好。

    【讨论】:

    • 有多种方法;我也喜欢带有时间戳(无随机性)的“节点 ID”的想法。您可以通过对加密散列(例如 SHA1)进行异或来轻松创建具有任意位数的节点 ID。当然,位数越少,节点 ID 冲突的可能性就越高。您提到的“唯一性”实际上被其他 Guid 算法用于处理向后的系统时钟,以保持每个节点 ID 的时间戳唯一。但归根结底,您将很难找到一种能够保证比纯随机性更少的碰撞的解决方案。请记住,这就是 .NET Guid 所做的一切......
    • 虽然 1/2^64 的概率仍然是一个非常小的数字,但我不喜欢纯随机数的想法。但我考虑过完全省略主机名哈希,只是将随机数增加到 30 位。但这不是一个好主意,因为对于 n 个离线客户端,这会使冲突的机会达到 2^30*n。对于 100 个客户,这大约是千万分之一。运气不好的人可能会在那里中大奖......
    • 1/2^64 == 18 septillion 之一(1 septillion == 1 万亿 1 万亿,或 100 万)。如果你走完全随机的方式......
    • 不,是 1/2^32 由于生日效应。
    • @erikkallen:实际上,碰撞的概率开始时非常小(1/2^64),并随着 id 的生成而增长。您正在考虑的是在预期发生碰撞之前生成的 id 数量(碰撞概率超过 50% 标记)。在 2^32(超过 40 亿)个 id 处,发生冲突的概率为 50%。不过,感谢您提出生日效果;我确实忽略了它。 :)
    【解决方案2】:

    如果空间不是问题,那么为什么不只使用 2 列 64 位宽,然后使用 8 字节将 guid 分成两半,然后将它们转换为 64 位数字并将其存储在 2 列中,那么如果您确实需要升级到另一个系统,您仍然是独一无二的,您只需要考虑重新加入 2 列。

    【讨论】:

    • 然后我必须为每个连接比较两个数字。这不会大大降低性能吗?
    • 好吧,您将在您的密钥中包含一个额外的列[我假设 guid 是一个密钥],所以您会有一些细微的变化,但这样您就不会丢失系统上的 Guid可以支持它,您可以为那些不支持它的解决方法。
    【解决方案3】:

    为什么要自己写?为什么不直接生成一个统一的随机数?它会很好地完成这项工作。只需抓住前 X 个数字,其中 X 是您想要的任何大小……比如 64 位。

    有关 SQL Server 中 RAND()NEWID() 的信息,请参阅 here,这实际上只是对 GUID 与随机数生成器的对比。另外,如果您需要比System.Random 更随机的东西,请参阅here

    【讨论】:

    • 完全随机数不是一个好主意,恕我直言。随着数据库变得越来越大,我不想担心重复和奇怪的错误。至少需要以某种方式集成时间戳。虽然考虑了一下,但最好不要考虑秒数,只增加随机整数大小。这样我就可以有一个相当长的主机名哈希和一个相当长的随机数。
    猜你喜欢
    • 2012-09-23
    • 2014-03-05
    • 2012-06-02
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多