Проблема с запросом из двух таблиц

que_bunt

Новичок
Проблема с запросом из двух таблиц

Здраствуйте.
У меня есть две таблици:
users - id,login,pass,reg_date
images - id,user_id,name,add_date,file_name
связь users<->images один ко многим

как можно выбрать в одном запросе все поля из users + количество записей из images для каждого user_id?

есть вариант добавить в таблицу users поле images_number, и обновлять его при каждом внесении записи в images, но ведь нужную виборку можно осуществить и без дополнительного поля.

подскажите пожалуста как.
 

voituk

прозревший
[sql]
select users.*, count(images.id) as qty from images inner join users ON users.id=images.user_id group by user_id
[/sql]

-~{}~ 04.06.06 17:05:

если надо ещё и пользователей без единого изображения, то надо не INNER JOIN а RIGHT JOIN
 

zerkms

TDD infected
Команда форума
вариант с дополнительным полем действительно лучше
если запросом то примерно так (не проверял):
[sql]
SELECT `users`.*, COUNT(`i`.*) FROM `users` `u` LEFT JOIN `images` `i` ON `u`.`id` = `i`.`user_id` GROUP BY `u`.`id`
[/sql]
 

voituk

прозревший
zerkms
вариант с дополнительным полем действительно лучше
Это почему же?
В плане нагрузки на БД - согласен
Но вплане роста слложности системы - не могу согласиться
 

zerkms

TDD infected
Команда форума
voituk
не нужно мыслить абстракциями. нужно решать те задачи, которые поставлены именно сейчас. если будет быстрее именно сейчас сделать дополнительное поле, то почему бы именно так и не поступить?
 

voituk

прозревший
zerkms
Ох уж эти "агил-девелоперы"...
А завтра прийдет новый разработчик на этот проект (или ты в отпуск уедешь), и при увеличении функциональности благополучно будет забывать обновлять поле images_qty.
Использование такого поля должно быть описано в документации.

Разговор о нормальных формах реляционных БД, какие при этом нарушаются, я тут вообще заводить не хочу - это должен знать каждый.

Ещё у меня есть БОЛЬШИЕ сомнения, что в данном случае "будет быстрее именно сейчас сделать дополнительное поле".
 

zerkms

TDD infected
Команда форума
Ещё у меня есть БОЛЬШИЕ сомнения, что в данном случае "будет быстрее именно сейчас сделать дополнительное поле".
один простой запрос будет быстрее того же запроса + LEFT JOIN по таблице с 10000, по которой дополнительно будет ещё и делаться группировка
 

voituk

прозревший
Ну, предположим на 10000 - это ещё не имеет значения.
Вот на миллионах - согласен.
Потому подобную денормализацию БД стоит делать при высоких нагрузках, там, где нет возможности реализовать кеширование.

Но, опять же повторюсь, это увеличивает сложность клиентского кода, обслуживающего эту БД, и как следствие, увеличивает количество ошибок при развитии и поддержании проекта.
 

zerkms

TDD infected
Команда форума
это увеличивает сложность клиентского кода
клиентский код разницы не видит совершенно. клиентскому коду совершенно безразлично
SELECT `cnt`
или
SELECT COUNT(*) AS `cnt`

а про 10000 - тем не менее быстрее, не важно на сколько - это был ответ на фразу
Ещё у меня есть БОЛЬШИЕ сомнения, что в данном случае "будет быстрее именно сейчас сделать дополнительное поле".
 

que_bunt

Новичок
voituk,zerkms - большое спасибо!

а в общем я согласен что для больших проектов лучше сделать дополнительное поле - меньшая нагрузка, но для небольших (как у меня счас) думаю это лишнее.

ещо маленький вопрос, просто в мануале не описано, или я не понял - какая разница между INNER JOIN, RIGHT JOIN, LEFT JOIN - ?
обясните пожалуста если это не слишком долго.
 

voituk

прозревший
клиентский код разницы не видит совершенно. клиентскому коду совершенно безразлично
SELECT `cnt`
или
SELECT COUNT(*) AS `cnt`
В таком примитивном случае - да!
В вот при добавлении записи с БД - уже надо помнить что надо кроме INSERT в таблицу изображений, делать UPDATE в таблице пользователей. С удалением аналогично.
Вот и прийдется теперь править весь код обновления записей.
Это хорошо что если он ещё инкупсулирован в библиотеки/классы, а если нет?
[small]что-то мне подсказывает, что если человек задает подобные вопросы, то скорее всего ответ "НЕТ"[/small]

А ещё я никак не пойму почему сущность "пользователь" в данном случае должна что-то знать о сущностях "изображение"?
Завтра система перекроится под другой проект и будут не изображения а доступа...
Прийдется ещё и код сущности "пользователь" править - нехорошо, батенька.
 

Барби

Новичок
но с другой то стороны, если у пользователя много всяких данных, счётчики чего угодно, а вывести нам нужно сводную таблицу этих счётчиков... сложность запроса в случае с групировкой тогда возрастёт многократно... нада искать более лояльные методы
 

zerkms

TDD infected
Команда форума
Барби
никогда нельзя говорить категорично в таких вопросах
пока ситуация не изучена обстоятельно, нельзя говорить во сколько сложность чего возрастёт
да, запрос будет длиннее, но не факт что выполняться он будет хотя бы на 20% дольше
 

Барби

Новичок
я говорил о сложности запроса в контенте его нагрузки на бд. и конечно говорил не для случая, когда у нас в базе 10 пользователей по 5 картинок
 

zerkms

TDD infected
Команда форума
Барби
а ты сможешь количественно оценить этот запрос и на обозрение аудитории результаты исследования опубликовать? либо сколь либо достоверно предсказать планируемый выигрыш?
а то может цель средства совсем не оправдывает?
 

Барби

Новичок
на обстрактном уровне говорить о конкретных процентах глупа. а про вполне определёный случай я думаю ты и сам в силах засечь время выполнения запросов как минимум.
и вдогонку, почитай мои посты, лично я никакого метода не предлагал, я лишь пытался заострить внимание на грабли
 
Сверху