Как быстрее выбрать изображения из БД (mysql php)?

Проектирую движок аукциона. (высоконагруженную систему)
Имеем 2 таблицы Лот и Изображения. На одном лоте может быть до 10 изображений.

Как быстрее будет и менее ресурсоемко для сервера:

1. Связь Один ко многим. Лот -< Изображения.

В таблице Лота есть поля: Ид., Название, описание, цена...
В таблице Изображения: Ид., Ид.Лота, путь...

2. Связь не принципиальна

В таблице Лота: Ид., Название, описание, цена, строка с Ид. Изображений ('1001, 1002,..')
В таблице Изображений Ид., путь.

Вопрос: Быстрее делать выборку через JOIN с двух таблиц. Или средствами php делать выборку id-шников изображений. и потом брать из таблицы их (без JOIN).

Допустим: в базе 100 000 лотов и 500 000 изображений.
и при 50 000 000 лотов и 100 000 000 изображений.

Можете кидать ссылки на статьи. Можете советовать другие варианты. Но должно летать!
Заранее спасибо!
  • Вопрос задан
  • 3077 просмотров
Пригласить эксперта
Ответы на вопрос 5
AMar4enko
@AMar4enko
Отличные советы вам дал человек в очках. Храните изображения в базе, доставайте их оттуда скриптом, из скрипта отдавайте! Зачем нам реверс-прокси, энджиниксы всякие.
А по поводу вашего вопроса - самое правильное, это взять PostgreSQL, где есть типизированный массив в качестве типа столбца.
А если без него, то я бы сериализовал массив имен файлов и пихал их в поле типа text, потому что:
- вероятней всего вы не будете использовать одно изображение в нескольких лотах
- вы не будете выполнять поиск по названиям файлов изображений
В этом случае вы избавлены от накладного запроса в БД для получения изображений - получили запись, десериализовали массив имен и все, можете отдавать.
Ответ написан
@kaasius
Небольшой лайфхак - вам надо шардить картиночки, иначе при 100М картинок в одной папочке произойдет что-то очень плохое. Поэтому вижу такой вариант - делаете структуру папок примерно как:
images/
            001/
                   <id лота нач. на 001>/
                                                     все картинки лота
            002/
                   <id лота нач. на 002>/
                                                     все картинки лота


Тогда вы сможете по id лота получить все картиночки, вообще не дергая БД. Ну и сможете со временем изменить схему шардирования. Сможете даже разнести картинки по разным серверам, если понадобится, то есть получите горизонтально масштабируемую архитектуру.
Ответ написан
Все данные пишите в одну таблицу (да, будет большая таблица с кучей полей). Изображения храните в виде файлов с именами в виде id. Это бесспорно самый быстрый вариант
Ответ написан
Комментировать
seriyPS
@seriyPS
Правильно понял, что вам нужно вывести на странице несколько лотов с картинками?
Храните в 2-х таблицах и выбирайте 2-мя запросами, 2-й с id IN (...).
В postgresql могли бы использовать array_agg + JOIN и выбирать всё одним запросом. Но тут тоже лучше бенчмаркать что лучше - 2 запроса или один, но с JOIN и аггрегацией.
Ответ написан
Комментировать
@eandr_67
web-программист (*AMP, Go, JavaScript, вёрстка).
Быстрее всего будет работать вариант, когда имена файлов изображений хранятся непосредственно в таблице "лот" - чтобы JOIN вообще не было. Будет ли это 10 полей типа VARCHAR, или одно поле, хранящее сериализованный массив - не принципиально.

Но хранить, разумеется, надо именно имена файлов, а не сами файлы.

@kaasius прав в том, что картинки надо раскидывать по множеству папок. Но должно быть 2 уровня папок, а не один и в механизме распределения он ошибается. Раскидывать надо не по id, а случайным образом. Например, взять md5(uniqid($id_лота, true)) и первые 3 символа использовать в качестве имени папки, а следующие 3 - в качестве имени подпапки. Получится что-то вроде /images/48e/da3/имя_файла.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы