Por ejemplo, digamos que quiero buscar un usuario y todos sus números de teléfono y direcciones de correo electrónico. Los números de teléfono y los correos electrónicos se almacenan en tablas separadas, Un usuario para muchos teléfonos / correos electrónicos. Puedo hacer esto con bastante facilidad:
SELECT * FROM users user
LEFT JOIN emails email ON email.user_id=user.id
LEFT JOIN phones phone ON phone.user_id=user.id
El problema * con esto es que está devolviendo el nombre del usuario, el DOB, el color favorito y toda la otra información almacenada en la tabla de usuarios una y otra vez para cada registro (usuarios correos electrónicos registros de teléfonos), presumiblemente consumiendo ancho de banda y ralentizando los resultados.
¿No sería mejor si devolviera una sola fila para cada usuario y dentro de ese registro había una lista de correos electrónicos y una lista de teléfonos? También haría mucho más fácil trabajar con los datos.
Sé que puede obtener resultados como este utilizando LINQ o quizás otros marcos, pero parece ser una debilidad en el diseño subyacente de las bases de datos relacionales.
Podríamos solucionar esto usando NoSQL, pero ¿no debería haber un punto medio?
¿Me estoy perdiendo algo? ¿Por qué no existe esto?
* Sí, está diseñado de esta manera. Lo entiendo. Me pregunto por qué no hay una alternativa con la que sea más fácil trabajar. SQL podría seguir haciendo lo que está haciendo, pero luego podrían agregar una o dos palabras clave para hacer un poco de posprocesamiento que devuelva los datos en un formato anidado en lugar de un producto cartesiano.
Sé que esto se puede hacer en un lenguaje de secuencia de comandos de su elección, pero requiere que el servidor SQL envíe datos redundantes (ejemplo a continuación) o que emita varias consultas como SELECT email FROM emails WHERE user_id IN (/* result of first query */)
.
En lugar de que MySQL devuelva algo parecido a esto:
[
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"email": "[email protected]",
},
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"email": "[email protected]",
},
{
"name": "Jane Doe",
"dob": "1953-02-19",
"fav_color": "green",
"email": "[email protected]",
}
]
Y luego tener que agrupar en algún identificador único (¡lo que significa que también necesito recuperar eso!) del lado del cliente para reformatear el conjunto de resultados como lo desea, solo devuelva esto:
[
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"emails": ["[email protected]", "[email protected]"]
},
{
"name": "Jane Doe",
"dob": "1953-02-19",
"fav_color": "green",
"emails": ["[email protected]"],
}
]
Alternativamente, puedo emitir 3 consultas: 1 para los usuarios, 1 para los correos electrónicos y 1 para los números de teléfono, pero luego los conjuntos de resultados de correo electrónico y número de teléfono deben contener el ID de usuario para que pueda hacer una copia de seguridad de los mismos. con los usuarios que previamente busqué. Nuevamente, datos redundantes y post-procesamiento innecesario.