Powiedzmy na przykład, że chcę pobrać użytkownika oraz wszystkie jego numery telefonów i adresy e-mail. Numery telefonów i e-maile są przechowywane w osobnych tabelach, jeden użytkownik do wielu telefonów / e-maili. Mogę to zrobić dość łatwo:
SELECT * FROM users user
LEFT JOIN emails email ON email.user_id=user.id
LEFT JOIN phones phone ON phone.user_id=user.id
Problem * polega na tym, że zwraca nazwę użytkownika, DOB, ulubiony kolor i wszystkie inne informacje przechowywane w tabeli użytkowników w kółko dla każdego rekordu (użytkownicy wysyłają e-maile z rekordów przez telefon), prawdopodobnie pochłaniając przepustowość i spowalniając w dół wyników.
Czy nie byłoby lepiej, gdyby zwrócił jeden wiersz dla każdego użytkownika, a w tym rekordzie znajdowała się lista e-maili i lista telefonów? Ułatwi to również pracę z danymi.
Wiem, że możesz uzyskać takie wyniki za pomocą LINQ lub być może innych frameworków, ale wydaje się, że jest to słabość w projekcie baz relacyjnych baz danych.
Możemy to obejść za pomocą NoSQL, ale czy nie powinno być czegoś pośredniego?
Czy coś brakuje? Dlaczego to nie istnieje?
* Tak, jest zaprojektowany w ten sposób. Rozumiem. Zastanawiam się, dlaczego nie ma alternatywy, z którą łatwiej byłoby pracować. SQL może nadal robić to, co robi, ale może dodać słowo kluczowe lub dwa, aby wykonać trochę przetwarzania końcowego, które zwraca dane w formacie zagnieżdżonym zamiast produktu kartezjańskiego.
Wiem, że można to zrobić w wybranym przez Ciebie języku skryptowym, ale wymaga to, aby serwer SQL wysłał zbędne dane (przykład poniżej) lub abyś mógł zadawać wiele takich zapytań SELECT email FROM emails WHERE user_id IN (/* result of first query */)
.
Zamiast zwracania przez MySQL czegoś podobnego do tego:
[
{
"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",
}
]
A następnie trzeba zgrupować na jednym unikalnym identyfikatorze (co oznacza, że ja też muszę go pobrać!) Po stronie klienta, aby sformatować zestaw wyników w odpowiedni sposób, po prostu zwróć to:
[
{
"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"],
}
]
Alternatywnie mogę zadać 3 zapytania: 1 dla użytkowników, 1 dla e-maili i 1 dla numerów telefonów, ale następnie zestawy wyników dla adresu e-mail i numeru telefonu muszą zawierać identyfikator_użytkownika, aby móc dopasować je z powrotem do użytkowników Wcześniej ściągałem. Znowu zbędne dane i niepotrzebne przetwarzanie końcowe.