【问题标题】:How to generate a unique text id for a online resource如何为在线资源生成唯一的文本 ID
【发布时间】:2011-04-04 10:37:22
【问题描述】:

我想生成一个唯一的 ID,该 ID 将在 URL 中用于标识特定资源。原则上它与 pastebin.com 等相同。

id 和资源不是很秘密,但我希望它是这样你就不能减少一个 id 然后获取另一个用户资源。我正在考虑一个CHAR(8),它在 URL 中看起来不错,并且仍然足够大以减少猜测的机会。但是我如何生成这个?对于 INT,您可以使用 auto_incrementprimary key 来确保唯一性。

但如果我按顺序执行以下操作

  1. 在我的应用程序中生成CHAR(8)
  2. 确保此 ID 不存在。
  3. 如果不存在,则存储,否则转到 1。

我必须将 2. 和 3. 包装在原子事务中。

但是有更好的方法吗?或者我不应该关心检查(2.),因为冲突不会经常发生。如果有帮助,我会使用 MySql 和 .Net (C#)。是否有可能以某种方式“加密”一个自动递增的 int 作为 text-id 并以精确的 8(或 10)个字符再次解密。

我已经阅读了有用的Need a smaller alternative to GUID for DB ID but still unique and random for URL,但是 MySql 不支持使用 GUID(据我所知)。但也欢迎对线程中LongToShortCode 方法的质量发表评论。

注意:资源不能更改,只能查看。

最好的问候, 拉斯

【问题讨论】:

  • 不清楚您是尝试在 C# 中还是直接在 mysql 中生成此 id。为避免重复的可能性,您可以将数据库行 id 附加到唯一字符串,以便没有 2 是相同的......但它仍然无法仅减少 id 以获取上一个条目。
  • @GrandmasterB 在哪里生成 ID 并不重要,但我更希望它尽可能靠近数据库生成。 “您可以将数据库行 ID 附加到唯一字符串” - 您能更深入地解释您的意思吗?
  • 如果你有一个随机 id,ABCDEFG,并且想确保它在数据库中是唯一的,添加唯一的行 id,1234-ABCDEFG,其中 1234 是行 id。然后,您不必担心碰撞。但是,它会要求您在创建行之后将随机 ID 添加到数据库中,以便您可以获得所述 ID。或者,您可以将其作为 1234-ABCDEFG 输出给用户,即使在数据库中其第 1234 行的值 ABCDEFG - 只需在查询前将其拆分为“-”即可。
  • @GrandmasterB 我想再次访问资源会出现问题。可能有许多行具有相同的结尾文本 ID。
  • 如果唯一的行 ID 作为文本 ID 的一部分附加到它,则不会。

标签: c# mysql random auto-increment


【解决方案1】:

我想我会这样做: 一个 8 字符的文本 id 最多可以存储 64^8 = 2^48 的数字。

然后我将使用两列:

  • ID,INT 2^32 自动递增
  • 兰德,INT 2^16

然后,当我添加一行时,我会生成一个随机的 2^16 整数并将其放入新行中。然后简单地从两个数字组合生成文本 id。检索很容易两个 - 只需将其拆分并在数据库中进行简单查找。荒谬的简单解决方案应该消除行冲突并足够随机(2^16)以减少猜测。

我们将不胜感激有关此方法的反馈。

【讨论】:

    【解决方案2】:

    您可以使用 int 标识,然后在使用它之前对其进行加密/解密,但在重负载下可能不是最好的主意。

    【讨论】:

    • 您是否有一个正确实现的算法的链接,可以将整数转换为长度精确为 X(在我的情况下为 8)的文本?
    【解决方案3】:

    MySql 实现了 UUID。这似乎是具有不同名称的 GUID。因此,您仍然可以使用该选项。

    如果您仍打算使用char(8),那么您确实需要担心您的 ID 的唯一性,因为如果您正在查看提供的 URL,您可能不知道发生了违规行为,直到人们开始报告问题.

    【讨论】:

    • UUID/GUID 太大,很难剥离(查看其他 stackoverflow 线程)。资源不能更改,只能查看,所以不会有问题。本质上,我将提供类似于例如的东西。 pastebin.com
    【解决方案4】:

    以伪原子方式执行此操作的最简单方法是

    1. 生成随机字符串
    2. 存储字符串(实际上是保留它)
    3. 检查是否存在另一个
    4. 如果存在另一个,则删除刚刚创建的那个,然后返回步骤 1

    冲突仍然可能发生,但是当它们发生时,它会导致两个线程重试,在这种情况下这不是问题。

    编辑:我建议将加密哈希的前几个字符或其他内容用于您的生成函数,但这并不重要。

    【讨论】:

    • “存储字符串”是什么意思?如果我存储它,它确实存在并且可能会出现存储冲突。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2023-03-15
    相关资源
    最近更新 更多