【问题标题】:Generate unique id from unique string input从唯一的字符串输入生成唯一的 id
【发布时间】:2011-01-12 17:54:18
【问题描述】:

我有一个包含唯一字符串值列的表。字符串值的最大长度为 255 个字符。我想生成一个以字符串值作为输入的唯一 id。换句话说,我正在寻找一个字符串的紧凑表示。生成的唯一 ID 可以是字母数字。一个有用的功能是能够从唯一 id 重新生成字符串值。

是否有一个有效的函数来生成这样一个唯一的 id。一些方法可能是使用校验和或哈希函数。我想知道是否有标准的方法来做到这一点。

我正在使用 MySql 数据库和 java。

谢谢!

--edit:我正在寻找更紧凑的表示,而不仅仅是使用字符串本身。

【问题讨论】:

标签: java mysql uniqueidentifier


【解决方案1】:

选择正确的密钥并不容易。

你需要考虑:

  • 复制: 是否需要在不同服务器之间共享密钥?如果是这样,您很可能需要某种唯一的哈希或 guid。

  • 表格大小/插入次数: 您应该考虑到大多数 rdbms 按其(集群)主键的顺序将数据物理存储在硬盘驱动器上。现在想象一下,如果您在具有合理大小的表上插入以“a”开头的哈希值,会发生什么。是的,有索引填充,但最终它的完整和单行插入可能会导致硬盘驱动器上的几个 GB 移动。

  • 需要复制并且有大表? 两者都用。使用主聚集自动递增(长)整数键并在哈希列上定义唯一索引。

【讨论】:

    【解决方案2】:

    这与压缩有关。最简单的方法是对每个字符进行位打包并将每个字符降至最低位数。

    A-Z 是 26 个字符,小于 32(5 位)

    添加 a-z,它是 6 位(大约有 12 位模式剩余用于表​​示其他字符)。

    假设这对你来说已经足够了。所以你有 6x255 位,即 1530 位来存储你的字符串。 (191 字节)

    只使用大写字母会减少一点(减少到 159 个字节)

    您可以对其进行更多优化,但随后您必须进入一种压缩算法,该算法需要字符串中的特定语言或模式并优化这些模式。

    除非您可以进一步指定字符串的内容,否则您将无法获得所需的内容。对不起。 (如果您可以详细了解字符串的内容,请这样做。我们中的一个人可能会看到可以更好地“压缩”的模式)

    缺乏做你想做的事的能力是哈希表如此酷的原因。他们得到一个“最独特”的数字,然后有第二级分辨率来测试两个字符串散列到相同数字的情况。

    【讨论】:

      【解决方案3】:

      由于您使用的是 MySQL,请查看 CRC32

      http://www.bitbybit.dk/carsten/blog/?p=191

      【讨论】:

        【解决方案4】:

        “独特”有多独特?使用任何好的散列函数(MD5 适合大多数用途,并且可以通过 java.security.MessageDigest.getInstance("MD5") 轻松实现)可以让您获得一个非常可能是唯一的 128 位数字。使用哈希值会为您提供更小的 ID,碰撞的可能性更高。

        在 DB 中使用 auto_increment 字段,如果它适合您的设计,可能更容易实现,将真正保证唯一性,并且将使用比 MD5 的 16 字节更小的 ID。然后,您还可以满足通过键查找字符串的要求,而对于散列,您无法做到这一点。

        【讨论】:

        • 我的用例不能使用 auto_increment。我喜欢使用 MD5 值作为 id 的想法。还从@philfreo 帖子中发现 mysql 中有一个很好的 MD5 函数。我想我无法使用 MD5 哈希取回字符串是可以的。
        【解决方案5】:

        如果您有有限数量的频繁出现的字符串,则可以选择创建一个具有数字(自动递增)ID 的引用表,并在主表中对该引用表进行 FK。

        如果没有,您可以通过 GZIP 或任何其他压缩算法运行您的字符串(如果您需要检索原始文件)。

        如果您不需要检索原始数据,您需要的是 MD5 等哈希函数。

        【讨论】:

        • 压缩的问题在于,因为我将在 ID 中使用它,所以我希望它是人类可读的。所以可能是像 MD5 这样的好的哈希函数是要走的路。
        【解决方案6】:

        255 长的字符串比 64(或其他)长的数字有更多的可能性。是不可能的。添加一个 auto_increment 字段。

        【讨论】:

          【解决方案7】:

          如果您的数据库要求列包含唯一值,那么为什么不使用字符串本身呢?其他任何东西都只是编码/解码的另一个步骤。

          【讨论】:

          • 我正在寻找更紧凑的表示。
          • @pkrish:啊,好吧,所以是一个字符串的无损压缩,所以你不需要显示完整的 255 个字符?你研究过 ZIP 压缩吗?
          【解决方案8】:
          public String getUniqueId(String uniqueString) {
              return uniqueString;
          }
          

          除非 ID 有除“唯一”之外的任何其他限制。

          【讨论】:

          • 他说“一个紧凑的表示”——大概是一个较短的版本。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-08
          • 1970-01-01
          • 1970-01-01
          • 2013-02-09
          • 1970-01-01
          • 1970-01-01
          • 2011-09-24
          相关资源
          最近更新 更多