El mejor enfoque para fragmentar tablas MySQL es no hacerlo a menos que sea totalmente inevitable hacerlo.
Cuando está escribiendo una aplicación, generalmente desea hacerlo de una manera que maximice la velocidad, la velocidad del desarrollador. Optimizas la latencia (tiempo hasta que la respuesta está lista) o el rendimiento (número de respuestas por unidad de tiempo) solo cuando es necesario.
Particiona y luego asigna particiones a diferentes hosts (=fragmento) solo cuando la suma de todas estas particiones ya no cabe en una sola instancia de servidor de base de datos, la razón por la cual es escritura o lectura.
El caso de escritura es a) la frecuencia de escritura está sobrecargando los discos de este servidor de forma permanente o b) hay demasiadas escrituras en curso, por lo que la replicación se retrasa permanentemente en esta jerarquía de replicación.
El caso de lectura para la fragmentación es cuando el tamaño de los datos es tan grande que el conjunto de trabajo ya no cabe en la memoria y las lecturas de datos comienzan a llegar al disco en lugar de servirse desde la memoria la mayor parte del tiempo.
Solo cuando tienes para fragmentar lo haces.
En el momento en que fragmenta, está pagando por eso de varias maneras:
Gran parte de su SQL ya no es declarativo.
Normalmente, en SQL le dice a la base de datos qué datos desea y deja que el optimizador convierta esa especificación en un programa de acceso a datos. Eso es algo bueno, porque es flexible y porque escribir estos programas de acceso a datos es un trabajo aburrido que perjudica la velocidad.
Con un entorno fragmentado, probablemente esté uniendo una tabla en el nodo A con los datos del nodo B, o tiene una tabla más grande que un nodo, en los nodos A y B y está uniendo los datos de esta con los datos que están en los nodos B y C. Está comenzando a escribir resoluciones de unión basadas en hash del lado de la aplicación manualmente para resolver eso (o está reinventando el clúster de MySQL), lo que significa que termina con una gran cantidad de SQL que ya no es declarativo, pero expresa la funcionalidad de SQL de una manera procesal (por ejemplo, está utilizando sentencias SELECT en bucles).
Está incurriendo en una gran latencia de red.
Normalmente, una consulta SQL se puede resolver localmente y el optimizador conoce los costos asociados con los accesos al disco local y resuelve la consulta de una manera que minimiza los costos.
En un entorno fragmentado, las consultas se resuelven ejecutando accesos clave-valor a través de una red a múltiples nodos (con suerte con accesos clave por lotes y no búsquedas clave individuales por viaje de ida y vuelta) o presionando partes de WHERE
cláusula en adelante a los nodos donde se pueden aplicar (esto se llama 'empuje de condición'), o ambos.
Pero incluso en el mejor de los casos esto implica muchos más viajes de ida y vuelta en la red que una situación local, y es más complicado. Especialmente porque el optimizador de MySQL no sabe nada acerca de la latencia de la red (bueno, el clúster de MySQL está mejorando lentamente en eso, pero para MySQL estándar fuera del clúster eso sigue siendo cierto).
Estás perdiendo mucho poder expresivo de SQL.
Ok, eso es probablemente menos importante, pero las restricciones de clave externa y otros mecanismos SQL para la integridad de los datos no pueden abarcar múltiples fragmentos.
MySQL no tiene una API que permita consultas asincrónicas que funcione correctamente.
Cuando los datos del mismo tipo residen en varios nodos (por ejemplo, datos de usuario en los nodos A, B y C), las consultas horizontales a menudo deben resolverse en todos estos nodos ("Buscar todas las cuentas de usuario que no han iniciado sesión durante 90 días o más"). El tiempo de acceso a los datos crece linealmente con la cantidad de nodos, a menos que se puedan solicitar múltiples nodos en paralelo y los resultados se agreguen a medida que llegan ("Map-Reduce").
La condición previa para ello es una API de comunicación asíncrona, que no existe para MySQL en buen estado de funcionamiento. La alternativa es una gran cantidad de bifurcaciones y conexiones en los procesos secundarios, que es visitar el mundo de chupar en un pase de temporada.
Una vez que comience a fragmentar, la estructura de datos y la topología de la red se vuelven visibles como puntos de rendimiento para su aplicación. Para tener un rendimiento razonablemente bueno, su aplicación debe ser consciente de estas cosas, y eso significa que realmente solo tiene sentido la fragmentación a nivel de la aplicación.
La pregunta es más si desea fragmentar automáticamente (determinar qué fila entra en qué nodo mediante el hash de las claves principales, por ejemplo) o si desea dividir funcionalmente de forma manual ("Las tablas relacionadas con la historia de usuario xyz van a este maestro, mientras que las tablas relacionadas con abc y def van a ese maestro").
La fragmentación funcional tiene la ventaja de que, si se hace correctamente, es invisible para la mayoría de los desarrolladores la mayor parte del tiempo, porque todas las tablas relacionadas con su historia de usuario estarán disponibles localmente. Eso les permite seguir beneficiándose del SQL declarativo durante el mayor tiempo posible, y también incurrirá en una menor latencia de red porque la cantidad de transferencias entre redes se mantiene mínima.
La fragmentación funcional tiene la desventaja de que no permite que una sola tabla sea más grande que una instancia y requiere la atención manual de un diseñador.
La fragmentación funcional tiene la ventaja de que se realiza con relativa facilidad en un código base existente con una cantidad de cambios que no es demasiado grande. http://Booking.com lo ha hecho varias veces en los últimos años y funcionó bien para ellos.
Habiendo dicho todo eso, mirando su pregunta, creo que está haciendo las preguntas incorrectas, o estoy malinterpretando por completo su declaración del problema.