У меня в MySQL есть следующие таблицы:
team: id, name, [more stuff]
person: id, name, team, [more stuff]
entry: id, name, team, [more stuff]
registrations: id, event_id, team, status
registration_people: registration_id, person_id
registration_entries: registration_id, entry_id
Я хотел бы запросить базу данных и вернуть подробную информацию о каждом человеке и записи; сгруппированы по регистрации. С годами я научился делать все, что могу, в SQL. Однако я не вижу хорошего способа сгенерировать это в одном запросе без большой работы с PHP. Наивный способ сделать это - [псевдокод]:
$registrations = $model->get_registrations($event_id);
foreach ($registrations as $registration)
{
$registration['people'] = $model->get_people_in_registration($registration['id']);
$registration['entries'] = $model->get_entries_in_registration($registration['id']);
}
return $registrations;
Этот код выполняет много обращений к серверу, и его не следует использовать. Другая идея, которая у меня была, заключалась в том, чтобы сделать что-то вроде:
$registrations = $model->get_registrations($event_id);
$registration_entries = $model->get_registration_entries($event_id);
$registration_people = $model->get_registration_people($event_id);
foreach ($registrations as $r)
$reg[$r['id']] = $r;
foreach ($registrations_entries as $e)
$reg[$e['registration_id']]['entries'][] = $e;
foreach ($registrations_people as $p)
$reg[$p['registration_id']]['people'][] = $p;
return $reg;
Где get_registration_entries/get_registration_people выполняет соединение и захватывает все registration_entries, связанные с регистрациями в $event_id. Однако похоже, что я выполняю соединение в PHP; когда я смогу заставить SQL сделать это за меня. Я просто параноик или что-то здесь упускаю?






Концепция «делать как можно больше в SQL» действительна только тогда, когда она уменьшает объем данных, считываемых из базы данных, или количество обращений к базе данных. Если вам все равно нужно получить данные, какой смысл группировать их в базе данных? На PHP это сделать намного проще.
Вы должны сделать что-то вроде этого:
select r.registration_id, p.*
from registration_people rp, registrations r, person p
where /* your filter conditions on the "registration" table */
and rp.registration_id = r.id
and p.id = rp.person_id
(Я думаю, это почти то же самое, что и ваш второй подход)
Таким образом, вы получите все необходимые данные из базы данных и не более того. Теперь вы можете группировать результаты локально в PHP. Этот подход достаточно эффективен, поскольку вы получаете из базы данных ровно столько данных, сколько вам нужно, и не совершаете ненужных обращений к базе данных и обратно.
FryGuy: Я согласен, сортировка, присоединение и тому подобное обычно должны выполняться на стороне сервера. Однако в этом случае вы не можете группировать строки на стороне базы данных: конечно, вы можете запросить несколько наборов результатов, но это бессмысленно.
Что ж, на моей первой работе на стороне веб-сервера было много кода, который выполнял такие вещи, как сортировка и (простое) объединение, что было намного лучше на стороне БД, а также код, который делал много циклов. Думаю, это сделало меня параноиком.