2

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

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

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

谢谢!

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

4

8 回答 8

4

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

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

于 2010-02-03T18:50:07.717 回答
2

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

AZ 是 26 个字符,小于 32(5 位)

添加 az 并且它是 6 位(大约 12 位模式剩余的某处代表其他字符)。

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

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

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

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

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

于 2010-02-03T18:53:40.470 回答
1

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

于 2010-02-03T18:14:02.210 回答
1

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

于 2010-02-03T18:36:14.047 回答
1

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

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

于 2010-02-03T19:09:25.907 回答
0
public String getUniqueId(String uniqueString) {
    return uniqueString;
}

除非 ID 对它有任何其他限制,而不是“唯一”。

于 2010-02-03T18:09:27.543 回答
0

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

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

如果您不需要检索原始文件,那么您正在寻找诸如 MD5 之类的散列函数。

于 2010-02-03T18:42:37.420 回答
0

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

你需要考虑:

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

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

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

于 2012-08-30T15:56:29.607 回答