【问题标题】:Handling Random Id Storage处理随机 ID 存储
【发布时间】:2018-11-06 04:01:26
【问题描述】:

假设我们有一个像 YouTube 这样的应用程序,我们希望以随机方式为视频分配 ID,这样用户就无法遍历视频。例如。 https://www.youtube.com/watch?v=o4f5G9q_9O4

我为此搜索了解决方案,但到处都说非顺序 id 会严重损害索引,并且使用递增 id 并公开它们是不安全的(我同意)。

这个 id 应该如何存储? id 不是顺序会损害索引吗?

PS:我正在使用 MySQL 来存储这些数据

【问题讨论】:

  • 您最关心的是执行full table scan,如果您有适当的索引和查询语句,您将不会这样做。 UUID 不需要(不需要)是连续的,AFAIK。按照链接页面的详细信息,尝试运行一些查询并让 MySQL EXPLAIN 它为每个查询做了什么。

标签: mysql database indexing database-design architecture


【解决方案1】:

随机字符串不必是主键。您可以拥有一个AUTO_INCREMENT 主键,用作其他表中的外键。此外,您可以拥有一个 unique_id 列,其中包含您在 URL 中公开的随机字符串。这可以有一个唯一的索引,这将提高查找效率。

这类似于用户表,其中您可能有一个连续的user_id,还有一个唯一的user_name 列,用于登录、发送消息、在帖子中显示等。

对于unique_id 列,您最好使用散列索引而不是B 树索引。不幸的是,在 MySQL 中,这仅在 MEMORY 存储引擎中可用,而不是 InnoDBMyISAM

【讨论】:

  • 但是索引随机值可能是个问题:blog.jcole.us/2014/10/02/…
  • @LucasPiske 效率不如索引结构化数据,但是如果你需要一个随机字符串,你有什么选择?
  • 换句话说,如果您可以在有序数据和无序数据之间进行选择,请使用有序数据。但是对于像这样的应用程序,你没有这个选择。
  • 我正在寻找不同的选择。我想我可能会让一些想法在我脑海中闪过。
  • Youtube 可能没有使用 MySQL。他们可能正在使用具有更灵活索引模式的数据库,例如唯一字符串的哈希索引。
【解决方案2】:

目前的讨论是关于 UUID 有多糟糕。虽然我同意,但我认为它不适用于这里。

您的情况是:给定 one 看起来随机的 id,获取它所引用的 one 记录。正确的?您不必担心获取多个“连续”记录。

生成随机密钥:UUID 相当庞大;你可能想要一些更短的东西。取一些唯一字符串的MD5() - 可能是AUTO_INCREMENT id 与秘密种子连接。然后转换成base64,这样就不会太长了。 (警告:注意可能会弄乱 url 的特殊字符)。

获取:使用该密钥作为PRIMARY KEYUNIQUE 密钥将在随机性方面花费一些东西。但我怀疑这只会占应用程序开销的一小部分。

【讨论】:

    【解决方案3】:
    1. 组成一个随机字符串。
    2. 尝试插入具有UNIQUE 约束的列。
    3. 如果它插入,恭喜标识符是你的。
    4. 如果重复失败,请返回步骤 1。

    如果您有足够长的字符串和足够强大的随机数生成器,那么冲突应该很少见。如果您使用所有字母(大写/小写)和数字,那么您可以使用大约 20 个不太可能发生冲突的字符标记。

    较短的键有效,但碰撞会更频繁。通过生成几百万个密钥自行测试,看看平均需要多少次重试。

    【讨论】:

    • 我曾想过这样做,但我阅读了很多关于非顺序键(UUID、随机字符串等)从长远来看会如何伤害你的文章。由于 B-Tree 索引的工作方式。
    • 除非您有可衡量的性能问题,否则不要为此感到压力。这将是 YouTube 规模的问题,但不会少于 10 亿条记录。
    猜你喜欢
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2019-03-16
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多