Join 切分如何处理相关表的连接?

Join 切分如何处理相关表的连接?,join,relational-database,sharding,database-partitioning,Join,Relational Database,Sharding,Database Partitioning,当我读到关于分片的内容时,作者似乎没有考虑分片表必须连接到的其他表(即使他们将分片描述为“原始数据库的子集”)。然而,这是一种非常普遍的情况,我仍然不知道如何处理。一些作者提到了分片表引用的“静态”表,这些表可以复制到每个分片(例如,国家)。但是,他们没有提到引用切分表的表 假设我们运行一个社交网络,并意识到我们的用户表(id、名称)由于大量写入或大小(或两者兼而有之)而无法再适应单个服务器。因此,我们决定将其水平划分为多个分片(例如,4个,id为1-1000的用户转到一个分片,1001-200

当我读到关于分片的内容时,作者似乎没有考虑分片表必须连接到的其他表(即使他们将分片描述为“原始数据库的子集”)。然而,这是一种非常普遍的情况,我仍然不知道如何处理。一些作者提到了分片表引用的“静态”表,这些表可以复制到每个分片(例如,国家)。但是,他们没有提到引用切分表的表

假设我们运行一个社交网络,并意识到我们的用户表(id、名称)由于大量写入或大小(或两者兼而有之)而无法再适应单个服务器。因此,我们决定将其水平划分为多个分片(例如,4个,id为1-1000的用户转到一个分片,1001-2000转到另一个分片等),并选择一个User.id作为分片键。由于用户表通常连接到其他表,因此我们将记录从引用给定用户或其引用的表移动到相应的分片(这是一个相当大的挑战,因为关系通常是可传递的,例如,表a可能引用引用分片表C的B)。为了简化事情,我们可以决定将除用户表之外的所有数据全部复制到所有碎片中。到目前为止还不错

然后,想象一下朋友表(id,user\u id,friend\u id),其中包含关于谁是谁的朋友的信息,并引用用户表。用户1001有2个朋友,2002和3003,他们位于不同的碎片上。因此,如果我们需要获取关于用户1001个朋友的信息,我们将不得不执行2次交叉碎片连接。即使我们最初设法将所有相关用户放在同一个碎片上,用户也可以从不同的碎片添加新朋友。我们无法将此朋友4004移动到用户1001,因为来自同一碎片5的其他用户也可以将他作为朋友


老实说,我无法理解在执行分片时如何处理这种情况,我还没有看到任何资源对此进行解释。

在分片表之间进行连接时,您通常希望优化的是在分片之间传输的数据量

如前所述,有5种类型的分布式联接,按从最优先到最不优先的顺序排列:

  • 本地/并置引用表联接
  • 这是您在
    国家/地区表中提到的示例。每个节点都在本地保留此表的副本,因为它很少更新。利与弊是显而易见的:不是所有的东西都可以标记为参考表,但不涉及数据移动

  • 本地/并置分布式表联接
  • 这意味着向联接所需数据所在的所有节点发送查询。然后,对总体执行结果进行聚合。缺点是表需要在连接条件中涉及的列上进行分片。这是最具可伸缩性的算法,因为它在进行连接之前不涉及数据移动

    这将适用于您的
    朋友
    表格示例。据推测,您的
    Users
    表将由用户id设置键,该id也是shard键,因此将有一个索引,因此查询应该很快

  • 远程分布式表联接
  • 群集中的所有节点都将它们拥有的连接两侧的数据发送到单个节点,以便该节点可以运行连接。这种类型的联接只有在联接所涉及的行数较少时才能很好地执行

  • 广播加入
  • 如果正在执行连接,其中一方有一个大数据集,另一方有一个小数据集,则此类型会将小数据集发送到大数据集,并且具有大数据集的节点会在本地执行连接

  • 洗牌加入
  • 这是运行分布式连接的最昂贵但最灵活的方法。由于连接中涉及的许多行被复制到其他节点以执行连接,因此需要大量数据移动