分片如何处理加入相关表格的问题?

时间:2017-11-24 11:19:07

标签: join relational-database sharding database-partitioning

当我阅读有关分片的内容时,看起来作者并未考虑其他表格,必须将分片表连接到其中(即使它们将分片描述为"原始数据库的子集&#34 )。然而,这是一个非常常见的情况,我仍然不知道如何处理它。一些作者提到"静态"由分片表引用的表,可以复制到每个分片(例如,国家)。但是,他们没有提及引用分片的表格。

想象一下,我们运行社交网络并意识到我们的用户表( id,名称)不再适合单个服务器,因为写入量很大或者因为大小(或两者兼而有之)。因此我们决定将其水平划分为多个分片(例如,4,因此id为1-1000的用户转到一个分片,1001-2000转到另一个分片等)并选择 User.id 作为分片键。由于用户表通常连接到其他表,我们将引用给定用户或由其引用的表中的记录移动到相应的分片(这是一个很大的挑战,因为关系通常是可传递的,例如,表A可以引用参考分片表C)的B。为了简化操作,我们可以决定将除User表之外的所有分片复制到所有分片中。到目前为止一切都很好。

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

老实说,我无法弄清楚在执行分片时如何处理这样的情况,而且我还没有看到任何资源解释这一点。

1 个答案:

答案 0 :(得分:4)

在分片表之间进行联接时,通常要优化的是跨分片传输的数据量。

有5种类型的分布式联接,如here所述,从最喜欢的到最小的排列:

  1. 本地/关联参考表联接

这是您在Countries表中提到的示例。每个节点都在本地保留此表的副本,因为它很少更新。优点和缺点很明显:并非所有内容都可以标记为参考表,但是不涉及数据移动。

  1. 本地/并置的分布式表联接

这意味着向连接所需要的数据所在的所有节点发送查询。然后,汇总整体执行结果。缺点是需要将表分片到连接条件中涉及的列上。这是可扩展性最高的算法,因为它在进行连接之前不涉及任何数据移动。

这将与您的Friends表示例一起使用。大概,您的Users表将由用户ID(也是分片键)进行键控,因此将有一个索引,因此查询应该很快。

  1. 远程分布式表联接

集群中的所有节点将连接两侧的数据发送到单个节点,以便它可以运行连接。这种类型的联接仅在联接所涉及的行数较少时才能很好地发挥作用。

  1. 广播加入

如果您要进行联接,则其中一侧的数据集较大,而另一侧的数据集较小,则此类型会将较小的数据集发送到较大的数据集,而具有较大数据集的节点将在本地进行联接

  1. 随机加入

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