Этот хитрый LEFT JOIN

Введение (можно и пропустить).

Рано или поздно, так или иначе, любому программисту связанному с системами хранения данных (как MySQL, к примеру) приходится сталкиваться с проблемой соединения таблиц. (Здесь и далее, условимся, речь идёт о связке PHP + MySQL). Вообще сразу скажу, чего я имею ввиду. Вот, предположим, есть у нас пара таблиц — users и user_ip_address. В программке Navicat наваял некую схемку, чтобы было проще представить себе структурку:

Mysql Join
Mysql Join

Кроме того, я добавил так называемый Foreign Key к таблице user_ip_address, связав её с users. Запрос выглядит так:

ALTER TABLE `user_ ip_address`
ADD CONSTRAINT `ip_to_user`
FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;

Теперь если, скажем мы удаляем запись о пользователе в таблице users, БД сама удалит все связанные данные в таблице user_ip_address. ON UPDATE можно не ставить. Foreign Keys — очень мощная и кошерная штука. Она здорово облегчает работу, перекладывая заботу о целостности данных на плечи БД.

Так вот, в общем и целом, эти таблицы описывают структуру с юзером, и его айпишниками. В таблице users есть три пользователя — alex, john & verner, у Алекса и Джона есть записи в таблице user_ip_addresses, а у Вернера — нет. Собственно, нас интересуют только и исключительно поля user_id в таблице user_ip_address, и поле id в таблице users. Как вы уже догадались, они связаны по этим полям. И вот, представим себе ситуацию, что вам надо сделать выборку всех пользователей с соответствующими им ip… Работёнка не такая уж и тривиальная поначалу. Обычно новички (да и я в своё время) делают как… сначала делают выборку всех пользователей, запросом типа:

 SELECT * FROM `users`; 

А потом благополучно перебирают получившийся массив в цикле на PHP, и на каждой итерации совершают ещё по запросу, вида

 SELECT * FROM `user_ip_address` WHERE `user_id`='{$uid}'; 

Нет, я ничего не говорю, метод рабочий, но если у вас, допустим, форум с 1000 пользователей — сервер загнётся, потому как это 1001 запрос. Если надо просто получить список ip, то можно сделать и так: Читать далее Этот хитрый LEFT JOIN