【问题标题】:Ruby UUID and uniqueness, for an IDRuby UUID 和唯一性,用于 ID
【发布时间】:2011-03-16 16:21:28
【问题描述】:

我需要一个 6 字符的字母数字 ID 用于我的 rails 应用程序,该 ID 将呈现给系统用户,并且在我系统中的所有对象实例中必须是唯一的。我预计不会超过几千个对象实例,所以 6 个字符远远超出我的实际需要。

此时,我在 Rails 应用程序中使用 UUIDTools gem 来生成 uuid。我应该使用哪种 UUIDTools 生成方法,以及我应该从生成的 uuid 的哪一端获取 6 个字符,以保证唯一性?

例如,如果我生成ef1cf087-95c9-4868-bd95-cea950a52b58,我是想从它的前面使用ef1cf0,还是从后端使用a52b58

...作为旁注/问题:我会错吗?有没有更好的办法?

【问题讨论】:

    标签: ruby uuid uniqueidentifier


    【解决方案1】:

    没办法。 UUID 被认为是唯一的,因为它很长并且几乎不可能生成相同的 UUID。如果您将其修剪为 6 个字符,那么您将大大增加重复的可能性。您必须使用递增的 id 或完整的 UUID。

    只有确定性生成 (id(x + 1) = id(x) + 1) 才能保证唯一性。 UUID 不保证,6个字符的保证更小。

    其他选项是创建 ID 生成服务,它将具有单一方法 getNewId 并将保留足以提供唯一 ID 的知识。 (最简单的情况——计数器)

    【讨论】:

    • 递增 ID 和完整 UUID 不是选项。为我提供生成唯一的 6 位字母数字 ID 的选项。
    • @Derick Bailey 没有。您可以通过统计(UUID 案例)或通过共享先前生成的 id 的知识(增量)来实现唯一性。随机 6 个字符不属于任何类别。
    • 天啊!对不起...不小心点击了反对票,它不会让我撤消它...说投票被锁定,除非答案被编辑。
    • @Derick Bailey 我添加了一些信息,以便您可以删除downvote,我希望它也有用
    • 您总是可以使用 base-36 编码 (0-9a-z) 递增的整数 id。这将为您提供一个字母数字标识符,但保证唯一性。
    【解决方案2】:

    当您说增加 ID 不是一种选择时,是因为您不希望用户看到您正在使用的方案,还是因为生成必须是无状态的(即,您无法跟踪您生成的所有 ID)?

    如果是前者,那么您可以生成一个 ID,检查您是否已经使用过它,如果是,则生成另一个新 ID。 (如果我走错了路,这似乎很明显很抱歉。)你可以这样做:

    while id = rand(2**256).to_s(36)[0..5] 
       break unless Ids.exists?(id)
    end
    

    其中Ids.exists?(id) 是does-this-already-exist 方法。

    【讨论】:

    • 天哪,这个算法会有有趣的 O 符号数字吗!
    • 是的,它是生成密钥(常量)的成本加上检查冲突的成本(如果表在内存中,则取决于散列函数)。鉴于 Derick 说他只生成了几千个密钥,因此不太可能发生冲突。
    • 这应该是公认的答案,即使它令人反感。
    猜你喜欢
    • 2011-07-30
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2014-02-03
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多