使用自增ID还是SHA1哈希作为MySQL的主键?

6

我可以将自增id字段作为我的主键,也可以使用sha1哈希。

那么我应该选择哪一个呢?

在性能方面,哪一个更好?


1
你应该根据你的应用程序来选择。就性能而言,我会选择不需要计算昂贵哈希的选项。 - eggyal
我的2个表涉及到存储一个sha1哈希,它与每一行相关联。我认为在2个表中作为varchar(40)列的使用比1个varchar(40)和2个int列更加不利。 - cgwebprojects
@cgwebprojects 2个char(40)(无需varchar)为80字节(取决于字符集)。1个char(40)和2个int是48字节。此外,索引在int上比char(40)更快。 - Corbin
谢谢,这正是我想要解决的问题,我会将它改为 CHAR :) - cgwebprojects
3个回答

22

在一些应用场景中,您可能需要使用全局唯一ID(UUID/GUID):

  1. 您希望(或正在)使用分片策略来扩展写入。您不希望分片节点重复键
  2. 您希望能够安全地移植数据从一个节点到另一个节点保留键。如果您想保持外键关系的完整性,则此操作至关重要。
  3. 您的应用程序也可以离线使用(上门销售上门维修等),其中离线应用程序定期与“真相源”进行同步。您希望这些离线键是唯一的,而无需进行远程调用。否则,您需要考虑一种重新组织键和关系的策略。使用自动递增的策略,并取决于您使用的RDBMS,这可能是一个非常繁琐的任务。

如果您没有上述或类似的用例,您可以使用自动递增id,如果这使您感到舒适;但是,您可能仍然想考虑UUID/GUID。

权衡:

关于UUID/GUID键的速度/大小有很多不同的观点。最终,这是一种权衡,并且有很多方法可以在数据库中获得或失去速度。理想情况下,您希望将索引存储在RAM中,以尽可能快地运行;但是,这是您必须权衡其他考虑因素的折衷。

有关UUID/GUID的其他考虑因素:

  1. 许多RDBMS可以生成UUID。
  2. 您还可以通过您的应用程序生成UUID(您不必依赖于RDBMS来生成)。
  • 开发人员/测试人员可以轻松地将数据从环境移植到另一个环境,并使应用程序按预期工作。这是一个经常被忽视的用例,但它是使用UUID/GUID策略的更强案例之一。
  • 有些数据库专为离线使用优化(CouchDB),其中UUID就是你所得到的。

  • 1

    使用自增ID。

    • ID不一定只能生成,也可以递增。
    • 哈希更适合用于存储密码。
    • 使用SHA哈希可能会得到重复的键。机会很小但是确实存在。
    • ID更易读。
    • ID是一种插入历史记录。您知道哪个记录是最后插入的(最高ID)。

    2
    你很可能会先达到整数存储的极限,而不是找到SHA哈希冲突。同样,一旦你进入一个有阴影的数据库,自动增量就会变得痛苦。 - mjsa

    1
    几乎肯定是自动递增的整数。创建和搜索速度更快,大小更小。例如,如果您有另一个引用它的表,您希望它通过整数主键还是通过sha1哈希引用它?整数会更有意义,并且效率会高得多(很多!)。

    再次感谢!由于我在一个表中存储了一个sha1,我不知道是否应该使用相同的sha1将其链接到另一个表中,但如果自动递增更好,那就这样吧! - cgwebprojects
    自增ID比通过sha1哈希链接更适合关系型数据库的设计。整数ID很小,非常快速地进行索引,并且将它们递增对于数据库来说非常便宜。sha1会使索引变得更大、更慢,并且正如Juergen D所指出的那样,它们容易发生冲突。(他的答案实际上可能应该被接受,因为它涵盖了我所说的一切+冲突问题) - Corbin
    你能想象使用自增ID来分片数据库吗?实际上不行,因为Instagram已经经历过了:http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram 自增ID难以扩展。 - mjsa

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接