Por exemplo, digamos que eu queira buscar um usuário e todos os seus números de telefone e endereços de email. Os números de telefone e e-mails são armazenados em tabelas separadas, um usuário para muitos telefones / e-mails. Eu posso fazer isso facilmente:
SELECT * FROM users user
LEFT JOIN emails email ON email.user_id=user.id
LEFT JOIN phones phone ON phone.user_id=user.id
O problema * disso é que ele retorna o nome do usuário, a data de nascimento, a cor favorita e todas as outras informações armazenadas na tabela de usuários repetidamente para cada registro (os usuários enviam e-mails para registros de telefones), presumivelmente consumindo largura de banda e diminuindo a velocidade abaixo os resultados.
Não seria melhor se retornasse uma única linha para cada usuário e, dentro desse registro, houvesse uma lista de e-mails e uma lista de telefones? Isso tornaria os dados muito mais fáceis de trabalhar também.
Eu sei que você pode obter resultados como esse usando o LINQ ou talvez outras estruturas, mas parece ser uma fraqueza no design subjacente dos bancos de dados relacionais.
Poderíamos contornar isso usando o NoSQL, mas não deveria haver meio termo?
Estou esquecendo de algo? Por que isso não existe?
* Sim, foi projetado dessa maneira. Entendi. Gostaria de saber por que não há uma alternativa mais fácil de se trabalhar. O SQL pode continuar fazendo o que está fazendo, mas pode adicionar uma ou duas palavras-chave para fazer um pós-processamento que retorna os dados em um formato aninhado, em vez de um produto cartesiano.
Eu sei que isso pode ser feito em uma linguagem de script de sua escolha, mas exige que o servidor SQL envie dados redundantes (exemplo abaixo) ou que você faça várias consultas como SELECT email FROM emails WHERE user_id IN (/* result of first query */)
.
Em vez de o MySQL retornar algo parecido com isto:
[
{
"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",
}
]
E, em seguida, tendo que agrupar algum identificador exclusivo (o que significa que também preciso buscá-lo!) Do lado do cliente para reformatar o conjunto de resultados como você deseja, basta retornar o seguinte:
[
{
"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"],
}
]
Como alternativa, posso emitir 3 consultas: 1 para os usuários, 1 para os e-mails e 1 para os números de telefone, mas os conjuntos de resultados de e-mail e número de telefone precisam conter o user_id para que eu possa compará-los com os usuários Eu peguei anteriormente. Novamente, dados redundantes e pós-processamento desnecessário.