Normalmente, os dados são divididos em fragmentos de uma maneira que permite evitar JOINS entre servidores. Porque esta operação é difícil e cara. Se o seu exemplo for hipotético, eu recomendaria dividir todos os dados pelo campo user_id ou user_group_id.
Por exemplo, o fragmento A conterá todas as tabelas com informações de usuários que user_id % 3 =0, fragmento B - qual user_id % 3 =1, fragmento C - qual user_id % 3 =2. Portanto, a maioria dos JOINS necessários estará dentro de um fragmento. Para algumas consultas complexas entre servidores, você pode ter um armazenamento NO-SQL comum, como memcached ou Redis, que terá cópias dos dados necessários de todos os shards (é claro que não é uma cópia completa de todas as tabelas). Esses armazenamentos podem ser facilmente replicados em quantos servidores você precisar. É assim que os projetos highload funcionam.