Por ejemplo, supongamos 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 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 del usuario una y otra vez para cada registro (los usuarios envían correos electrónicos a los registros de los teléfonos), presumiblemente consumiendo ancho de banda y disminuyendo la velocidad abajo los resultados.
¿No sería mejor si devolviera una sola fila para cada usuario, y dentro de ese registro hubiera 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 usando LINQ o quizás otros marcos, pero parece ser una debilidad en el diseño subyacente de las bases de datos relacionales.
Podríamos evitar esto usando NoSQL, pero ¿no debería haber algún término medio?
¿Me estoy perdiendo de 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 realizar un pequeño procesamiento posterior que devuelva los datos en un formato anidado en lugar de un producto cartesiano.
Sé que esto se puede hacer en un lenguaje de script de su elección, pero requiere que el servidor SQL envíe datos redundantes (ejemplo a continuación) o que emita múltiples consultas como SELECT email FROM emails WHERE user_id IN (/* result of first query */)
.
En lugar de que MySQL devuelva algo similar a esto:
[
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"email": "johnsmith45@gmail.com",
},
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"email": "john@smithsunite.com",
},
{
"name": "Jane Doe",
"dob": "1953-02-19",
"fav_color": "green",
"email": "originaljane@deerclan.com",
}
]
Y luego tener que agrupar un identificador único (¡lo que significa que también debo buscarlo!) Del lado del cliente para volver a formatear el conjunto de resultados como lo desea, solo devuelva esto:
[
{
"name": "John Smith",
"dob": "1945-05-13",
"fav_color": "red",
"emails": ["johnsmith45@gmail.com", "john@smithsunite.com"]
},
{
"name": "Jane Doe",
"dob": "1953-02-19",
"fav_color": "green",
"emails": ["originaljane@deerclan.com"],
}
]
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 volver a emparejarlos con los usuarios Anteriormente fui a buscar. Nuevamente, datos redundantes y posprocesamiento innecesario.