我的主桌,Users
,存储有关用户的信息。我计划有一个UserId
字段作为表的主键。我可以完全控制这些键的创建和分配,并且我希望确保以提供良好性能的方式分配键。我应该怎么办?
您有几个选择:
- 最通用的解决方案是使用 UUID,如中指定的RFC 4122.
例如,您可以有一个STRING(36)
存储 UUID。或者您可以将 UUID 存储为一对INT64
或作为BYTE(16)
。使用 UUID 有一些陷阱,因此请阅读本文的详细信息answer.
-
如果您想节省一点空间并且绝对确定您的用户数将少于数十亿,那么您可以使用 INT64,然后使用随机数生成器分配 UserId。您想要确保自己的用户数量少于几十亿的原因是生日问题,一旦拥有 4B 用户,发生至少一次冲突的几率约为 50%,并且此后增长速度非常快。如果您分配的 UserId 已经分配给以前的用户,那么您的插入事务将会失败,因此您需要为此做好准备(通过在生成新的随机数后重试事务)。
-
如果有某个专栏,MyColumn
,在您希望将其作为主键的 Users 表中(可能是因为您知道您需要经常使用此列查找条目),但您不确定此列导致热点的趋势(例如,因为它是按顺序生成的或基于时间戳),那么您还有另外两个选项:
3a) 你可以“加密”MyColumn
并将其用作您的主键。用数学术语来说,您可以对键值使用自同构,这会产生混乱地打乱它们的效果,同时仍然不会多次分配相同的值。在这种情况下,您不需要存储MyColumn
完全分开,而是您只会存储/使用加密版本,并且可以在应用程序代码中必要时对其进行解密。请注意,此加密不需要是安全的,而只需要保证原始值的位以可逆的方式充分加扰。例如:如果 MyColumn 的值是按顺序分配的整数,则只需反转 MyColumn 的位即可创建一个足够混乱的主键。如果您有更有趣的用例,您可以使用类似的加密算法XTEA.
3b) 有一个复合主键,其中第一部分是ShardId
,计算为hash(MyColumn) % numShards
第二部分是MyColumn
。哈希函数将确保您不会通过将行分配到单个拆分来创建热点。有关此方法的更多信息可以找到here。请注意,尽管 md5 或 sha512 是很好的函数,但您不需要使用加密哈希。幽灵哈希也是一个不错的选择。选择正确数量的分片是一个有趣的问题,并且可能取决于实例中的节点数量;它实际上是避免热点的功率(更多分片)和读取/扫描效率(更少分片)之间的权衡。如果您只有 3 个节点,那么 8 个分片可能就足够了。如果你有100个节点;那么 32 个分片是一个值得尝试的合理值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)