Например, скажем, я хочу получить пользователя и все его номера телефонов и адреса электронной почты. Телефонные номера и электронные письма хранятся в отдельных таблицах, от одного пользователя до многих телефонов / электронных писем. Я могу сделать это довольно легко:
SELECT * FROM users user
LEFT JOIN emails email ON email.user_id=user.id
LEFT JOIN phones phone ON phone.user_id=user.id
Проблема * в этом заключается в том, что он возвращает имя пользователя, DOB, любимый цвет и всю другую информацию, хранящуюся в таблице пользователей, снова и снова для каждой записи (пользователи отправляют записи по электронной почте на телефоны), предположительно потребляя пропускную способность и замедляя вниз результаты.
Разве не было бы лучше, если бы он возвращал одну строку для каждого пользователя, и в этой записи был список электронных писем и список телефонов? Было бы намного проще работать с данными.
Я знаю, что вы можете получить такие результаты, используя LINQ или, возможно, другие фреймворки, но, похоже, это слабое место в структуре реляционных баз данных.
Мы могли бы обойти это, используя NoSQL, но разве не должно быть никакого среднего уровня?
Я что-то пропустил? Почему этого не существует?
* Да, он разработан таким образом. Я понял Мне интересно, почему нет альтернативы, с которой легче работать. SQL может продолжать делать то, что делает, но затем они могут добавить ключевое слово или два, чтобы выполнить небольшую постобработку, которая возвращает данные в вложенном формате вместо декартового произведения.
Я знаю, что это можно сделать на языке сценариев по вашему выбору, но для этого требуется, чтобы сервер SQL отправлял избыточные данные (пример ниже) или чтобы вы выполняли несколько запросов, например SELECT email FROM emails WHERE user_id IN (/* result of first query */)
.
Вместо того, чтобы MySQL возвращал что-то похожее на это:
[
{
"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",
}
]
А затем необходимо сгруппировать некоторый уникальный идентификатор (а это значит, что мне тоже нужно его получить!) На стороне клиента, чтобы переформатировать набор результатов так, как вы хотите, просто верните это:
[
{
"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"],
}
]
В качестве альтернативы я могу выдать 3 запроса: 1 для пользователей, 1 для электронных писем и 1 для телефонных номеров, но тогда в результирующих наборах электронной почты и телефонных номеров должен быть указан user_id, чтобы я мог сопоставить их с пользователями Я ранее принес. Опять же, избыточные данные и ненужная постобработка.