Habituellement, les données se divisent en fragments d'une manière qui permet d'éviter du tout les JOINS entre serveurs. Car cette opération est difficile et coûteuse. Si votre exemple est hypothétique, je recommanderais de diviser toutes les données par le champ user_id ou user_group_id.
Par exemple, le fragment A contiendra toutes les tables avec les informations des utilisateurs dont user_id % 3 =0, fragment B - quel user_id % 3 =1, fragment C - quel user_id % 3 =2. Ainsi, la plupart des JOINS nécessaires seront à l'intérieur d'un fragment. Pour certaines requêtes inter-serveurs complexes, vous pouvez avoir un stockage NO-SQL commun comme memcached ou Redis qui aura des copies des données nécessaires de tous les fragments (bien sûr, ce n'est pas une copie complète de toutes les tables). De tels stockages peuvent être facilement répliqués sur autant de serveurs que nécessaire. C'est ainsi que fonctionnent les projets à forte charge.