Xpoint
   [напомнить пароль]

Лучше картинки держать в базе данных или в папке?

[горячая]
2002-07-11 03:15:40 [обр] Neona [досье]
Мы тут поспорили с одним человеком что лучше:
-держать много(очень) картинок в папке и когда надо вызывать на страницу (для витрины)
-или загружать все в базу данных(mysql) и вызывать оттуда .
Мне кажется что загрузка в базу данных более универсальное решение.
Но хочется послушать мнения людей уже решивших этот ворос.
спустя 1 час 16 минут [обр] Дмитрий

Neona:
Лучше хранить на сервере...

Хранение в базе - не очень надежно, и, что не менее важно, увеличивает (сильно) размер и уменьшает скорость работы БД. Особенно если много(очень) картинок.

спустя 5 часов [обр] Сергей Сирик [досье]

Мнение о лучшести хранении картинок на сервере практически уже стало общим местом ... посему найти реально хранящих картинки в БД практически невозможно :)))

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

По поводу надежности - хранение в БД позволяет более просто оперировать сложными данными, управляемыми одним механизмом, сиречь СУБД. Без привлечения сторонних системы типа файловой.

В хранении картнок файлами бОльшую ИМХО значимость имеет факт того, что в этом случае картинки отдаются клиенту Апачем, и могут хорошо кешироваться на клиенте.

спустя 9 часов [обр] Peter Didenko [досье]
А есть какие-то агрументы в пользу того, что надо хранить картинки в MySQL? Особенно это интересует в свете того же http://host.ru/art/0002.html, например...
спустя 1 час 32 минуты [обр] Romik Chef [досье]
Ух ты! Сам Петр Диденко. Каких только знаменитых людей на икспойнте не встретишь!
Из аргументов за хранение в базе, я слышал только один - "все данные в одном месте и удаление одним запросом". Впрочем, Сергей это написал.
В общем, по-моему в статье все правильно написано. По указанному адресу она не открывается, у меня нашлась вот тут:
http://www.hosting.zenon.ru/art/0002.html
спустя 15 часов [обр] Peter Didenko [досье]
:)) Не открывается потому что там запятая после "html" :( Можно просто убрать и все. А про хранения картинок в базе.. Это непроизводительно. Во-первых, дополнительная огромная нагрузка на SQL. Во-вторых, картинки выдаются пользователю как файлы и не зачем придумывать новые сущности - пусть лежат файлы на диске. Веб-сервер их поднимет и покажет пользователю. Это сильно быстрее, чем доставать из базы (Вы ведь еще и CGI-ку для этого запустите, да? :). В-третьих, кэширование. Наверняка ведь такая картинка почему-нибудь не будет закэширована, а лучше ей таки попасть в кэши где можно, так как картинки это статика в чистом виде (во всяком случае, в рассматриваемом варианте). Так что, в общем, не надо в базу картинки. Да, любой SQL умеет это. Да, любой язык, применяемый для веб-программирования, тоже это умеет. Даже /bin/sh. Хочется попробовать - попробуйте, но вот серьезные вещи так не делают.
спустя 6 часов [обр] Афонин Сергей AKA FRozen [досье]
Peter Didenko:Позволю не согласиться ....
для стандартных задач, будь то ешорп или какой нить представительский сайт, даже с навороченным движком - это избытоная вешь .., но для систем масштаба предприятия, где надо поизводить загрузку и выгрузку информации оспользуя только вордовский документ с картинками - это както, что нужно ...
спустя 24 минуты [обр] Neona [досье]
Я думала поместить в базу ради контроля-что бы знать соответствует ли товар картинке, не потерялась ли картинка на пути между сервером и локальной сетью, не забыли ли отсканировать. Ведь если картинок тысяч 50, как их контролировать? Хотя я думаю тоже есть методы, но не такие очевидные.
спустя 1 час 14 минут [обр] Romik Chef [досье]

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

И тем более странно видится мысль о хранении картинок в базе после рассуждений о скорости.

спустя 19 минут [обр] Афонин Сергей AKA FRozen [досье]
привожу пример:
PIII Xeon 500, 512 мозга, 5 райд на сказке ... MSSQL + ASP(ADO,JScript,VBsctipt,С++(компоненты)) = АСУ предприятия + сайт предприятия с системой обновления информации для "тупых секритарш", которые только понимают, что надо найти файл на диске Ц(преимущественно на декстопе) и нажать кнопочку "обновить", с рапределённой системой доступа - бла -бла -бла ... и так дале ...
вот в какой задаче я вижу нужность хранить картинки в базе ... (обязательное условие:"отсутвие ФТП-доступа как такового")...
спустя 6 часов [обр] Дмитрий Котеров [досье]

Согласен с утверждением о том, что если картинок МНОГО, а записи, которые на них ссылаются, текучи (часто добавляются и удаляются), во имя простоты можно пожертвовать производительностью и хранить картинки в базе. Однако с одним "но": кэширование ведь никто не отменял, не правда ли?.. То есть, доставать картинку из базы достаточно только при первом запросе, а дельше просто делать внутренние редиректы на этот "достатый" файл, вот и все!

Пример на PHP будет выглядеть примерно так (вызов: /img/image.php?id=N, где N — это ID той картинки, которая хранится в базе):

<?
$url="/img/$id";
$pic=$DOCUMENT_ROOT.$url;

if(!file_exists($pic)) {
   $data = loadPictureFromDatabase($id);
   $f=fopen($url,"wb"); fwrite($f,$data); fclose($f);
}
# Это ВНУТРЕННИЙ редирект, который выполняет сам
# Апач, а не браузер, поэтому работает мгновенно.
# То, что редирект внутренний, говорит отсутствие "http://".
Header("Location: $url");
?>

Этот способ взял все преимущества от обоих методов:
— от метода хранения в файле — очень высокую скорость.
— от метода хранения в базе — легкую реализацию «текучести кадров»; теперь, делая бэкап БД, можно не вспоминать, что «черт, забыл сделать бэкап /img — вот влип!».

Чтобы не связываться с кривым URL-ом, можете перехватывать 404-ю ошибку, вот так:

ErrorDocument 404 /img/image.php

В этом случае все будет работать еще быстрее, но, увы, возможность проверки, не изменилась ли картинка с тем или иным id, отпадает. Надеюсь, мысль ясна.

Однако все это оправдывает себя только в случае, когда картинки небольшие (ибо место в БД у хостеров обычно в несколько раз дороже места на винчестере).

спустя 7 часов [обр] Udjin [досье]
Друзъя - этот вопрос уже неоднократно обсуждался
Смотрите/ При хранении картинки в базе
Картинку из базы вытаскиваем -> собираем в файло -> ложим на диск -> кешируем при отдаче клиенту
При хранении на диске
Из базы берем линк -> кешируем имидж при отдаче клиенту
Для решения вопроса обхода кеширования некоторыми ретивыми Администраторами - инициировать рандом и отдавать картинку с уникальным GET клиенту чем отдовать ее потоком из базы поедая ресурсы системы и получая не гарантированный результат при сборке картинки браузером
ИМХО, хранение картинок в базе принципиально только для задач где упор делает на целостность данных. Ну и как академический вопрос/ типа доставай - наливай и между анекдотами и женщинами - кстати - а ты хранишь картинки где - в базе или на диске? ;-))
спустя 4 часа 34 минуты [обр] Давид Мзареулян [досье]
Если главное на вашем сайте - картинки, их много, и они большие, то, видимо, хранить в базе их не надо. Но если картинка у вас - просто некое поле в общей структуре данных, возможно, отсутствующее, и не очень большого размера, то вполне можно пожертвовать толикой производительности ради удобства, ничего страшного в этом нет. Тем более, что все современные БД прекрасно знают, что такое BLOB-s и умеют с ними работать. Только, конечно, надо их кэшировать на клиенте. Только, конечно, не через создание файлов, за что боролись-то?:))) Просто при выдаче картинки скриптом надо выставлять ей правильные header-ы, только и всего.
спустя 56 минут [обр] Romik Chef [досье]
Удобство сомнительное.
Польза сомнительная.
вред возможный (резалки баннеров с удовольствием сожрут)
Пользователю не сохранить по-человечески.
За такие оправдания "Для разработчика удобнее" в былые времена вообще канделябрами били и в приличное общество не пускали.
спустя 40 минут [обр] Давид Мзареулян [досье]

Romik Chef:
>> Пользователю не сохранить по-человечески.
>> резалки баннеров с удовольствием сожрут

По этим пунктам можно поподробнее?

спустя 1 час 29 минут [обр] Romik Chef [досье]
Имя картинки бровзер откуда будет брать?
Резалки баннеров режут по расширению. Если под картинку маскируется скрипт.
Кстати, про загрузку, совершенно лишнюю, сервера, кажется упомянуть забыли.
Хотим показать 10 картинок на странице - запускаем 10 скриптов. В легкую поднимаем загрузку сервера в 10 раз. На пустом месте.
спустя 11 минут [обр] Давид Мзареулян [досье]
Romik Chef:
Это проблемы ЧПУ, а не хранения картинок.
спустя 16 минут [обр] Romik Chef [досье]
Скажи проще - это проблемы юзеров.
И все сразу встанет на свои места.
спустя 1 минуту [обр] Давид Мзареулян [досье]
Romik Chef:
Если у программиста криворукость - то, конечно, у юзера будут проблемы, кто же спорит.
спустя 11 минут [обр] Афонин Сергей AKA FRozen [досье]
Romik Chef,Давид Мзареулян: ну вы ещё подеритесь ...
спустя 1 час 13 минут [обр] Дмитрий Котеров [досье]

Romik Chef:
про нагрузку это ты зря - грошовая она, я уже писал, как можно все сделать через 404-ю ошибку. И, действительно, это пробема ЧПУ (вернее, одно из ее решений — использовать ErrorDocument).

Давид Мзареулян:
кэширование практически всегда делается через создание файлов, потому что так удобнее и быстрее. Кэширование — это вообще такая технология, что не важно, через что она сделано — главное, дает прирост производительности за счет увеличения необходимой [дисковой] памяти, которую в любой момент можно очистить без потери работоспособности. Поэтому фраза «за что боролись» несколько непонятна — фактически, те картинки, которые после вытаскивания из базы попадают в файлы, никому, кроме «товарищу Быстродействию», не нужны, и их можно спокойно удалять или не учитывать при переносе сайта.

То есть, здесь единственное что, из-за чего может весьтись спор — это ЦЕНА дискового места, обычного и в БД. С точки зрения целостности выгоднее хранить картинки в БД, но это дороже по месту, в то время как хранить ссылки на картинки — дешево, но потенциально опасно для целостности. Вопрос быстродествия тут не стоит: ведь даже Hello world можно написать так, что она будет 2 часа запускаться.

спустя 48 минут [обр] Romik Chef [досье]

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

Вот хранение файлов в базе с последующим кэшированием, отдачей каждого прозрачного скриптами - это как раз и напоминает Hello World в сто строк.

Проще надо быть. Вообще, сама идея дикая - перегружать базу бинарниками только из боязни, что не будет сбэкаплена директория с картинками!

спустя 8 часов [обр] VIG [досье]

А об чем, собственно говоря, крик, прошу прощения?

  1. Вопрос начинает иметь смысл, только когда картинок много, скажем, тысячи и десятки тысяч.
  2. Блобы для базы штука, в общем-то, чужеродная.
  3. Скорость намного выше из файловой системы. Чтобы добиться того же из базы, нужно строить ручками собственную систему обеспечения или имитации кэширования, причем, что самое смешное, не на клиенте, а на сервере.
  4. Целостность и надежность намного лучше для базы.

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

  1. Картинки храним в файлах.
  2. В базе храним ссылки (имена файлов).
  3. Полностью закрываем доступ по записи к директории с картинками, кроме специально обученной процедуры ведения, связанной с базой и поддерживающей целостность.
  4. Ну и дополнительные затычки-примочки. Обработка случая, когда файла по ссылке все-таки не оказалось, несмотря на все предпринятые меры. Получения списка картинок, на которые почему-то нет ссылок. И тому подобное.
спустя 2 часа 34 минуты [обр] Udjin [досье]
При все моем уважении к профессионализму сторонников БЛОБ в базе, смею предположить, что опыта работы с действительно большими объемами и нагрузками у них недостаточно (если сие предположение ошибочно - то другие мои предположения будут более болезненны для них или для меня :) - смотрите конец поста.
Я принимаю как необходимость динамическую генерацию картинки или иного примитива/элемента по параметрическому запросу к базе, но слабо себе представляю Бизнес задачу с хранением в ней блобов.
Действительно - работать будет - но по факту - геморроя куда больше чем выгоды
Корень зда не в том что технология плоха/хороша и ресурсов мало/много поедает, - он в другом месте.
В операторе работающем с этими имиджами и в "хейдеке" который вызывает поддержка таких решений.
Пример:
Когда база раздуется гигов так до 500 по причине плохо подготовленных имиджей, а сайты партнеров откажутся прнинимать наборы данных, - встает вопрос о обработке в пакетном режиме всего массива имиджей (денежки заказчик теряет) ...
Дальше сами додумаете :-))
Таких примеров, НЕ УМОЗРИТЕЛЬНЫХ, у меня еще есть :-)
ИМХО, - лень двигатель прогресса.
Хророший программер, - ленивый программер: делаешь 1 раз, - работает пока железо не умрет
Если же времени много, делать нечего, вздурилося работы ради работы, "семплов" или "крути", - то блобы в базу :-))
VIG:
Золотые слова :-))
to ALL:
Вновь поднимаю вопрос, который задавал знатокам блобов еще много месяцев назад, после очередной зарубы на подобную тему:
Чем закончилась заморочка с отдачей потокового видео клиентам из базы данных? (Oracle)
PS
Кто нас рассудит?
Реальность нас окружающая, полагаю.
Серъезный проект/задача пользущие имиджи из базы (под серъезными я понимаю задачи уровня eBay - Yahoo shopping - SQUID) будут считаться веским аргументом в пользу блобов.
Критерий оценки аргумента выведем сообща дабы минимизировать субъективизм.
спустя 6 часов [обр] Дмитрий Котеров [досье]

Тему разрослась до такой степени, что чужие посты, похоже, вообще уже никто не читает, потому что по нескольку раз поднимается один и тот же вопрос и предлагаются одни и те же решения ;-)

Поэтому резимюрую еще раз. Мне не совсем понятны те споры, которые тут ведутся, ибо по некоторым вопросам решение можно вынести совершенно односзначно, а по другим — сказать, что «все зависит от сложности задачи».

Как заметил VIG, возиться с картинками в базе имеет смысл в том случае, если их МНОГО. Это — ПЕРВЫЙ и самый важный фактор. То есть, мы не рассматриваем здесь какие-нибудь скрипты портфолио, гостевые книги и т.д., а рассматриваем, например, Интернет-магазин с тысячами наименований товаров, когда для каждого товара есть картинка, а удаление товара ведет к удалению картинки.

ВТОРОЙ фактор — выбирая, БД использовать или файлы, руководствоваться соображениями быстродействия НЕЛЬЗЯ, ибо оба способа работают С ОДИНАКОВОЙ СКОРОСТЬЮ (за счет применения технологии кэширования НА СЕРВЕРЕ). Утверждения о том, что это «двойная работа», можно считать несостоятельными, ибо я уже привел пример кратчайшего скрипта, который всем этим занимается (а также приводил рассуждения о том, что не важно, как реализовано кэширование [в частности, на файлах или нет], важно лишь, чтобы оно работало). Hello world в 100 строк тут совершенно не при чем, ибо для Hello world 100 строк — это явная избыточность, тогда как кэширование — прямая необходимость, решающая множество задач «одним махом» (об этом также ниже). Кэширование еще хорошо тем, что от него можно в любой момент отказаться (в отладочных целях) без нарушения работоспособности (но за счет потери быстродействия), то есть, эта технология УСТОЙЧИВАЯ к ошибкам. Это нужно прежде всего почувствовать.

Вообще, поднимая спор о быстродейтвии, фактически поднимается спор о «грамотности» написания программы. То есть: «Если А написать НЕГРАМОТНО, то это будет медленнее, чем грамотно написанный Б => можно применять только Б, а А — выбросить в помойку». При этом мысли о том, что, может быть, грамотно написав А (благо это очень несложно, нужно лишь почувствовать идеологию технологии, которая зовется кэшированием), добьешься бОльших преимуществ, чем в Б, почему-то нет (это для Romik Chef).

ТРЕТИЙ фактор — целостность данных. Как и все в мире, технологии бывают УСТОЙЧИВЫМИ и НЕУСТОЙЧИВЫМИ. Назвать способ с кэшированием более сложным, чем способ с файлами, нельзя, ибо в последнем придется затратить гораздо больше усилий на поддержание целостности данных (и, если целостность нарушится, непонятно, что же делать), ем в первом — на извлечение картинки. Итак, можно заключить, что вариант с файлами потенциально НЕУСТОЙЧИВ, в то же время как вариант с БД — устойчив ВСЕГДА (как и вообще любой алгоритм с устойчивым ядром, на которое навешано кэширование). [Вообще, работает такой эмпирический принцип: правильное организованное кэширование никогда не снижает устойчивость алгоритма, на который оно «навешано». Устойчивость аглоритма (вернее, метода) определяется устойчивостью хранилища данных, которое в нем используется.] Устойчивость — это практически синоним целостности, а значит, вариант с БД имеет бОльшую целостность, чем вариант с файлами. Конечно, программисту при написании сложной (!) программы гораздо удобнее использовать алгоритмы с высокой устойчивостью (а не ставить карандаши на острие).

ЧЕТВЕРТЫЙ фактор — это цена дисковой памяти, которая в БД значительно дороже. Именно о нем говорят, когда упоминают «сотни гигабайт плохо упакованных картинок».

ПЯТЫЙ фактор — это необходимость частого проведения резервного копирования данных, а также необходимость переноса сайта туда-сюда. В случае частого бэкапа вариант с БД имеет преимущества, т.к. ислючает большинство ошибок, нарушающих целостность. Сюда же можно отнести ЛИШНИЕ ЗАВИСИМОСТИ в данных при использовании файлов (ибо нужно «завязываться» за URL директории с картинками, ссылки на которые стоят в базе). Из (почти математической) теории СУБД известно, что лишние (дублирующиеся) зависимости — это зло [я люблю называть этот процесс «завязыванием» за что-то].

Оффтопик: хотя я сам и не являлся сторонником хранения картинок в БД, после этого треда лично для меня сместились многие приоритеты (обычно так и бывает — как только что-то систематизируешь, начинаешь лучше это понимать). По крайней мере, для меня окончательно развеялся миф о потере быстродействия (на который так уповают ярые противники «картинок в БД», к их числу принадлежал и я сам).

спустя 31 минуту [обр] Давид Мзареулян [досье]
Дмитрий Котеров:
Очень разумно.
И есть ещё один момент. На любом достаточно мощном сайте (в смысле посещаемости) серверное кэширование, так или иначе, необходимо. Очень трудно отрабатывть сотни запросов в секунду, если результат каждый раз генерится скриптом из базы заново. От кэширования не уйти. А тогда - при правильно построенном кэшировании, уже всё равно, откуда растут картинки, из базы или из файлов.
спустя 43 минуты [обр] Udjin [досье]
Давид Мзареулян:
Посыл не верен потому как однобок :-)) Закешируйте шоп и почувствуйте на себе всю любовь кастомеров :-)
спустя 36 минут [обр] Афонин Сергей AKA FRozen [досье]
Udjin:;=)))
спустя 25 минут [обр] VIG [досье]

Дмитрий Котеров: все же позволю себе еще раз высказаться ...

По поводу быстродействия и памяти. Схема с кэшированием на сервере обладает следующими существенными, на мой взгляд, недостатками:

a1. Сравнительно быстро выполняется только второе и последующие обращения к файлу, да и то есть непроизводительные расходы на определение того, что файл в кэше уже есть и не устарел.
a2. Для задач без ярко выраженной области предпочтения, т.е. с приблизительно равномерными случайными запросами, кэширование не даст ничего, кроме дополнительной нагрузки и удвоения объема требуемой дисковой памяти.
a3. Необходима дополнительная процедура периодической очистки кэша, иначе его размер быстро превзойдет разумные пределы.
a4. И так далее, так что размеры скриптов для грамотного и полноценного решения будут не такими уж и маленькими, а результаты не такими уж и радужными, как Вам помн_и_лось, IMHO ...

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

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

В частности, затронули и вопрос с целостностью. Я, как водится, высказался, что реляционные БД вообще и оракл в частности не выдерживают никакой критики с точки зрения производительности, и то же самое можно делать в десятки-сотни, если не в тысячи раз быстрее. На что, естественно, получил ответ в стиле "зато мы делаем ракеты и перекрыли Енисей", дескать, пусть медленно, зато надежно, и замедление вовсе даже не зряшное, потому как вызвано заботой о целостности данных. И тому подобное ...

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


Тем не менее, этот спор заставил меня призадуматься, и через некоторое время я полностью поменял свое отношение к проблеме целостности данных.

Рассмотрим, например, следующую ежедневную задачку: запись таблицы А имеет обязательную ссылку на запись таблицы Б. При "традиционном" подходе ссылку делают required, а на удаление из таблицы Б ставят триггер, напрочь запрещающий это действие, если есть ссылки. Или наподобие того. И с чувством выполненного долга считают, что задача решена.

Решает ли такой подход множество реальных практических проблем. Отнюдь. Вот, навскидку:

b1. Что делать, если в базу нужно ввести запись А, для которой не существует записи Б. Есть два решения: а) написать себе записку "не забыть ввести запись А, когда появится запись Б" и прилепить сбоку монитора; б) "метод Джона Доу" - заводится фиктивная запись Б, означающая "данные неизвестны/отсутствуют" и делается ссылка на нее. Излишне говорить, что оба "метода" не выдерживают никакой критики.
b2. В каждую программу, удаляющую запись Б, надо вставить реакцию на отказ.
b3. Что самое главное, в каждую программу, читающую записи А, все равно надо вставить реакцию на ситуацию, когда ссылка на Б отсутствует или указывает в никуда. И не надо мне говорить, что такого не может случиться, поскольку ограничения целостности это запрещают. Теоретически - да, а на практике - еще как может.
b4. А что делать, если с течением времени выяснится, что такое ограничение неправильно, и в предметной области очень даже существуют объекты А без связанных с ними объектов Б? Полная катастрофа. Нельзя же просто так взять и удалить ограничение целостности, поскольку куча написанных прикладных программ может явно или неявно использовать наличие обязательной ссылки.
b5. И так далее ...

В силу этих и кое-каких других соображений, я сейчас применяю совершенно противоположный подход при проектировании структуры БД:

c1. Не вводится никаких ограничений целостности. Никаких обязательных полей, никаких триггеров, никакой ссылочной целостности и так далее. "Нет человека - нет проблемы".
c2. Прикладные программы пишутся в предположении, что всё, что угодно может рухнуть. Чуть-чуть больше кода, а на самом деле столько же, поскольку в грамотной программе, сделанной по принципам защитного программирования, такие проверки все равно нужны - на бога надейся, а сам ...
c3. Не делается никаких попыток поддерживать 100%-ую корректность данных в базе. IMHO, это вредная и недостижимая иллюзия, вроде полного искоренения преступности. Вместо этого ставится реалистическая задача: обеспечить, чтобы процент ошибок в базе не был выше некоего порога толерантности, когда ошибки начинают заметно сказываться на функционировании системы.
c4. Для этого делается некий набор простых пакетных процедур поиска несоответствий, генерящий отчеты об ошибках с указанием кто и когда их внес. Показатель качества работы сотрудников - минимальный размер отчета и пр.
c5. И тому подобное ...

Как показал опыт, системы получаются исключительно устойчивыми (robustness). С моей точки зрения, это качество прикладных систем намного важнее надежности (reliability), хотя и надежность тоже получается почти 100%-ая. А главное, общие трудозатраты на разработку и сопровождение не только не возрастают, но и заметно уменьшаются ...

Вот такие пироги. Причем практические, хотя все это звучит как жуткая ересь ...

спустя 2 часа 17 минут [обр] Neona [досье]

Действительно картинок должно быть очень много(10-100 тысяч).
Такой себе eshop.
Планирую делать на mysql поскольку денег на что-то более серьезное думаю пока не раскрутимся не выделят.
Поэтому пока вопрос с триггерами не стоит. И бэкап будет делается постоянно.
В начале поста меня почти убедили, что надо делать не в базе а в файлах.
Теперь наоборот.
Может монетку кинуть?

Но все равно интересное получилось общение. Спасибо участникам!

спустя 5 часов [обр] Дмитрий Котеров [досье]

VIG:
То, что Вы написали, очень интерено, и, ей-богу, если бы я был Вами, то оформил бы все это в статью и выложил на всеобщее обозрение (в библиотеку Вебклуба, например).

Тем не менее, все же хотелось бы попробовать опровергнуть некоторые утверждения, которые были выдвинуты в самом начале. Вы их озаглавили a1-a4. Итак...

a1. "Сравнительно быстро выполняется только второе и последующие обращения к файлу, да и то есть непроизводительные расходы на определение того, что файл в кэше уже есть и не устарел."
     — Я уже писал, что потеря быстродействия — это миф, ибо грамотно органгизованное кэширование НИКОГДА не приводит к проигрышу в быстродействии, если его применять грамотно. То же самое и здесь. Давайте рассмотрим Ваш пример — "определение того, файл в кэше или уже устарел". Еще с незапамятных времен в ЭВМ начали применять прерывания, ибо комп без прерываний — это как телефон без звонка: обладая таким телефонам, нам бы пришлось очень часто снимать трубку и проверять, не пытается ли кто-нибудь с нами соединиться [кстати, найдется ли здесь человек, который знает, из какой довольно древнуй книги эта замечательная цитата?..]. В нашем конкретном случае прерывание — это ни что иное, как 404-я ошибка, которая возникает, когда КЭШ ПУСТ. Итак, с затратами определения того, пуст ли кэш, мы разобрались — это не приводит к потере быстродействия.
     Давайте теперь посмотрим, как решается задача определения того, УСТАРЕЛ ли кэш. Нам нужно придумать решение, которое обладало бы теми же самыми свойствами, и оно действительно существует. Все дело здесь к сведениб задачи к предыдущей. То есть, как только кэш устаревает, об этом сообщается некоторому менеджеру кэширования (часть которого — это наш 404-й обработчик). Этот менеджер просто бурет и удаляет закэшированный рисунок вместе с файлом. Таким образом, при следующем запросе рисунок будет заново считан из базы. Итак, и в этом случае мы имеем нулевые затраты.
     Но давайте посмотрим, как же решается проблема инвалидации, если картинки хранятся не в базе, а в файлах. Легко заметить, что процесс почти полностью повторяет только что описанный — а именно, старый рисунок удаляется, а на его место копируется новый! Таким образом, весь спор — это лишь вопрос, откуда же берется новый рисунок: копируется из БД автоматически или же по FTP администратором (или через форму закачки).
      Я тут говорил об универсальном менеджере кэширования вот по какой причине. Некоторое время назад я этот менеджер писал, причем неоднократно (универсальный класс написать так и не удалось, просто руки не дошли). Многим может показаться странным, как же это один и тот же код менеджера может решать самые разные задачи, но, как ни странно (и как это часто бывает в ООП) такой код написать можно. Идея здесь очень проста. Кэш — это набор взаимосвязанных СУЩНОСТЕЙ (связь многие ко многим). Для каждой сущности определены две операции: инвалидация (удаление) сущности (при этом удаляются также и все связанные с ней сущности, кроме того, вызываются некоторые СОБЫТИЯ, если они определны) и проверка, валидна ли сущность (а также выдача времени последнего считывания сущности). Имеется интерфейс для добавления новых сущностей в систему, а также для СКВОЗНОГО чтения (если эта операция определена). Вот, собственно, через все это и можно легко организовать любое кэширование, в частности, которое было описано здесь.

a2. "Для задач без ярко выраженной области предпочтения, т.е. с приблизительно равномерными случайными запросами, кэширование не даст ничего, кроме дополнительной нагрузки и удвоения объема требуемой дисковой памяти. "
     - Я бы сделал здесь одну-единственную оговорку: как правило, класс Web-задач к этой области НЕ ОТНОСИТСЯ. А именно, благодаря равномерной и случайной загрузке вероятность того, что закэшированный ресурс будет просмотрен снова, практически равна единице (это, правда, не относится к баннерным системам, но они — это не Web-сайты, а мы сейчас рассматриваем только их).

a3. "Необходима дополнительная процедура периодической очистки кэша, иначе его размер быстро превзойдет разумные пределы."
     — Самое примечательное, что эта процедура — ОБЩАЯ для ЛЮБЫХ кэшируемых ресурсов и может быть встроена в менеджер кэширования (это я к тому, что размеры кода тут опять же константные и очень небольшие). Одно из решений — чистка тех кэшированных записей, обращение к которым производилось очень давно (благо, для файлов в Unix есть атрибут atime, время последнего чтения). Как Вы понимаете, чистка кэша на файлах не займет больше 3 строчек в программе, а при наличии универсального менеджера кэширования — ни одной строчки. Процессорного вреени это тоже займет крохи (естественно, чистить кэш надо не при каждом запросе, а, например, раз в час).

a4. "И так далее, так что размеры скриптов для грамотного и полноценного решения будут не такими уж и маленькими, а результаты не такими уж и радужными, как Вам помнилось, IMHO ... "
     — Я пытался подкрепить рассуждениями утверждение, что это не совсем так. Не знаю, получилось ли...

спустя 1 час 37 минут [обр] VIG [досье]

Дмитрий Котеров:

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

Параметры модели (приблизительно):

  N - число файлов
  S1 - средний размер файла (в первом приближении можно считать все файлы одинаковыми)
  S2 - средний размер файла в базе
  T0 - время обработки запроса файловой системой (веб-сервером)
  D1 - дополнительная нагрузка на вызов обработчика 404 ошибки
  D2 - время работы обработчика 404 ошибки на формирование файла

Далее для разных функций распределения запросов (от равновероятного до сильно смещенного) имитируется поток запросов и считаются интересующие характеристики, например:

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

И так далее.

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

Если же нагрузка на сервер возрастает (причем не обязательно на данную задачу, поскольку возрастание общей нагрузки эквивалентно уменьшению мощности сервера), ситуация будет мало-помалу меняться на противоположную. Те самые незначительные расходы - например, Вы неправы, считая вызов обработчика 404 бесплатным, хоть немного, но времени на это уходит - так вот, эти самые незначительные расходы в конце концов приведут к тому, что максимальная допустимая нагрузка для варианта с кэшированием из базы будет меньше, чем с файловой системой. Конечно, оно зависит от допустимого размера кэша, но, по моей оценке (из общих соображений), при равномерном распределении вариант с кэшированием из базы потянет раза в 3-4 меньшую нагрузку, чем файловый.

Вот такие рассуждения ...

спустя 6 часов [обр] Romik Chef [досье]

Неона.
Дима Котеров, как видно из обсуждения, рассуждает чисто теоретически и из духа противоречия. Просто рассматривает такую возможность. Ему интересно потеоретизировать на эту тему.
Тебе же надо писать реальный магазин. Я так понимаю, что там есть чем заняться, кроме как кэшированием картинок и обходом подводных камней, связанных с тем, что картинки показываются не по-человечески, а скриптами.

ВИГ предложил замечательную идею. Перед кодом, который выводит img src, стоит is_readable, и если файла нет, то отсылается письмо администратору, а выводится какая-нибудь дефорлтная картинка.
Все. Одна строчка.
Вместо того, чтобы писать еще один (и не один) скрипт, занимающийся показом картинки из базы, перенаправляющий в него...
Это мне напоминает, как меня мама в детстве учила вилкой есть. Я брал кусок руками, добросовестно насаживал на вилку, и отправлял в рот. Incredible Machine. Зачем делать просто, когда можно сделать сложно?

Вот представь ситуацию. Картинка не показывается.
Из файлов. Просто посмотришь сгенеренный html и проверишь пути.
Из базы. И куда ты побежишь искать? В базу? В обработчик 404? В скрипт, который показывает картинку? Спрашивать у юзера, за какой проксей и каким бровзером он смотрит?
Оно тебе надо?

спустя 3 минуты [обр] Romik Chef [досье]
Я, как всегда, лапидарно :-)
спустя 3 часа 29 минут [обр] Peter Didenko [досье]
Мды. Картинками Вы тормозите себе SQL. Если хотите из него доставать еще что-то кроме картинок, задумайтесь. Делайте путь /раздел/подраздел1/подраздел2/товар.jpg и формируйте такой путь в логике скрипта. Можете хранить пути к картинкам в SQL если сильно хочется. Вопрос: какой у Вас есть фактор в пользу того, чтобы делать динамичным то, что по природе своей статичное? Загрузку побольше создать? Это да.
спустя 1 час 29 минут [обр] Udjin [досье]
А примеров реальных с блобами чегой то не видать ... одни измышления и "мусолинье мизинца"
спустя 17 минут [обр] Сергей Сирик [досье]

У меня были реальные примеры с БЛОБами, один раз, когда хостер вообще не позволял на диску писать, приходилось все в БД засовывать. И картинки, и доковские файлы. Нагрузка правда небольшая была ...

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

спустя 12 минут [обр] Romik Chef [досье]
У отдачи файлов из файлов есть такой немаловажный плюс, что с точки зрения авторизации нет абсолютно никакой разницы с отдачей из БД. А вот с точки зрения расходования памяти - есть. 2хРазмер_файла как минимум. В базе и в скрипте.
А из файла делается passthru в выходной поток.
спустя 7 минут [обр] Давид Мзареулян [досье]
Странный спор... Как будто никто не понимает, что при сотнях тысяч картинок всё равно придётся писать систему управления оными. Как будто никто не понимает, что 100000 файлов в одном каталоге могут затормозить систему куда сильнее, чем любой, даже самый примитивный кэш. Вам всё равно никуда не уйти от подсистемы управления картинками. Будет ли это база, кэш, система подкаталогов - неважно, всё равно писать придётся. Странные люди - все хотят ничего не делать, но чтобы всё работало.
спустя 18 минут [обр] VIG [досье]
Давид Мзареулян: здесь имеется две большие разницы. Против системы управления, по-моему, никто и не возражает - нужно. А вот против хранения картинок в базе блобами ...
спустя 1 час 39 минут [обр] Николай Бубело [досье]
спустя 6 часов [обр] Дмитрий Котеров [досье]

Раз уж речь зашла о затратах на считывание 100000 имен файлов, нужно заметить, что одни только имена считать будет довольно быстро (запустите ls, если не верите), а вот если еще и атрибуты читать — тогда точно завал.

Другое дело, что чистить файлы программно гораздо сложнее, чем чистить БД. Если же файлы еще и по скорости нужно оптимизировать (например, разбить по директориям), то задача вообще становится довольно неприятной. Представьте, например, задачу: удалить все картинки, на которые в базе больше нет ссылок. Для этого потребуется сделать выборку из базы, а потом пройтись по файлам. В этом отношении чистка кэша — значительно более простой механизм, да и со стотысячными объемами там дело иметь не приходится.

спустя 1 день 15 часов [обр] Rodion Alukhanov [досье]

Хотелось бы высказать свое мнение. (Сразу предупреждаю, что читал эту нитку лишь выборочно).

Я имею опыт работы с несколькими SQL-серерами и стараюсь руководствоваться следующим принципом (Безусловно это применительно к случаю изменяющегося во времени большого (неограниченного) количества картинок): Если база и интерфейс к ней (будь то ADO или DBI) позволяет хранить картинки в базе без применения дополнительных (часто самопальных) компонент, то надо хранить В БАЗЕ. Если же мне предлагают самому переписать драйвер или dll-ку (так один раз было со старой версией Oraclе) или использовать OBDC драйвер там, где у меня уже все заточено под OLE-DB (так было с InterBase), то храню картинки на диске. Потому как программа тем надежнее, чем она проще!

спустя 5 минут [обр] Rodion Alukhanov [досье]
Обосновывать не буду. Все здесь так или иначе правы и вопрос этот уже чисто религиозный. Есть куча примеров когда лучше делать так и куча же когда надо делать иначе. Т.ч. это из разряда Windows против Linux или Intel против AMD...
спустя 1 час 10 минут [обр] Romik Chef [досье]
Неона, очередная ремарка для тебя.
Этот человек пишет настольные приложения.
То есть, его замечание сродни такому. Спорят - стоит ли возить кирпичи в жигулях. Тут приходит Родион и говорит: "Когда я работал на самосвале - завсегда кирпичи в кузове возил. Только выгружать надо руками. Аккуратно. А так-то кузов для кирпичей - самое место." Бывает, не сориентировался человек сходу. Выборочно читал.
Но резюме правильное сказал. Чем программа проще, тем она надежнее.
спустя 10 минут [обр] Romik Chef [досье]
Подумалось:
О чем мы вообще говорим?
Люди за каждую миллисекунду бьются, скорость отклика повышают, HTML в СТАТИКУ переводят!
А мы за идею! Мы и картинки в динамике показывать будем! Трудностей не боимся!
И вообще, повышение производительности - это религиозный спор!
спустя 4 часа 42 минуты [обр] Peter Didenko [досье]

Именно! Люди наверное просто не видели как перевод двух страниц в статику и убирание с них картинок выводят сервер из ступора :) Меня тут одно издание попросило написать статью с обзором проблем производительности на современных новостных ресурсах - ух я там разошелся.. На днях будет :)


Петр Диденко, http://ezhe.ru/fri/449/

спустя 6 часов [обр] Дмитрий

Дмитрий Котеров:
Знаете, что обидно?
Что Вы людей учите. Сами еще не определились, а уже учите. В вашей же книге написанно "никогда не храните картинки в базе данных"... Сейчас Вы сами начинаете доказывать обратное. Интересно, а когда вы у Лебедева курсы читаете, Вы так же сегодня будете одно говорить, завтра другое, послезавтра третье?

P.S. В последнее время, я перестал заходить к Вам на куроводство. Просто там ничего не меняется. Менется только то, где вы зарабатываете. Школа Лебедева. Не уподобляйтесь. Быстро растеряете своих учеников.

спустя 7 часов [обр] Давид Мзареулян [досье]
Peter Didenko:
О! А где именно можно будет прочитать? Не сочтите за оффтопикъ...
спустя 14 часов [обр] Дмитрий Котеров [досье]

Попов Дмитрий:
Вы хотите сказать, что лучше стоять на своем старом, пусть и не до конца правильном), мнении, чем поменять его под воздействием новых сведений?.. Увольте.

Например, вот глупый пример:

  1. Из пистолета бандиты убивают людей.
  2. Следовательно, пистолет — зло.
  3. Милиция применяет оружие.
  4. Следовательно, милиция — это зло.

Тут «гнилой» второй аргумент, верный лишь наполовину. Все зависит от того, кто пистолет применяет. Также и с картинками в базе — все зависит от того, ПРАВИЛЬНО ли организуется технология хранения (и использования!) картинок в базе, или же неправильно. Если неправильно — это зло. Если правильно — я уже писал.

Собственно, здесь вопрос не столько В БАЗЕ, сколько В ПРИМЕНИМОСТИ КЭШИРОВАНИЯ.

Вопрос этот, с моей точки зрения, НЕ религиозный, ибо я НЕ призываю повально хранить картинки в базе, а лишь аргументирую, почему это иногда оказывается довольно удобным решением. Все «за» и «против» уже приведены (а «ложные против» — опровергнуты), и Вы можете посчитать по пальцам, каких аргументов больше. Я также НЕ утверждаю, что нужно делать все «в лоб», как раз наоборот — говорю, что без применения кэширования идея хранения картинок в базе БЕЗУМНА. Повторюсь: Вы почему-то воспринимаете эту тему как так называемую «ложную альтернативу»: «Как лучше сделать — A, но некорректно, или же B, не ненадежно» (утрируя). Вместо того, чтобы склоняться ко второму варианту, может быть, лучше сделать A, но корректно?

Peter Didenko:
Ваша статья заведомо будет однобокой, ибо Вы в ней опишите, как плохо бывает, когда программа написана НЕПРАВИЛЬНО. Но неправильность программы еще не свидетельствует об ошибочности алгоритма. Новостная система — прекрасный пример, когда грамотно организованное кэширование способно сравнять скорость работы скриптов с загрузкой статики. И так — почти что во всех приложениях.

Медлительность — это обычно не свойство веб-технологии, а свойство ее реализации. Подчеркиваю, что речь идет именно во Web, потому что это весьма специфическая область.

спустя 8 часов [обр] Peter Didenko [досье]
Дмитрий Котеров: Уважаемый! Да Вы чего?! Народ вон тут вовсю интересуется как бы покруче отключить это кэширование, а то оно только портит все! Безусловно, ВСЕ допущения, мной сделанные, основаны на том, что люди избавляются от кэширования, а не грамотно им управляют. Я и писал: "если нормально закэшировать выданные картинки - будет хорошо, но вы этого наверняка делать не будете".
спустя 15 часов [обр] Neona [досье]
Я заинтересовалась серверным кэшированием.
В такой интерпретации я его(кэширование) раньше не встречала.
Получается что запоминаются запросы к серверу и результаты запросов(где-то в отдельном месте)? А потом по мере прохождения времени либо используются, либо удаляются?
Я правильно поняла механизм?
Тогда интересно как хранятся результаты и как потом подменяются при возникновении повторяющихся запросов?
спустя 1 день 2 часа [обр] Дмитрий Котеров [досье]

Peter Didenko:
отключать обычно хотят БРАУЗЕРНОЕ кэширование. Сейчас же речь — о СЕРВЕРНОМ.

Neona:
Да, Вы правильно поняли. Как хранятся и подменяются — вопрос отдельный, иногда специфичный для каждой задачи. Выше все подробно описано на примере картинок.

В народе говорят:
Кэширование — оно и в Африке кэширование.
Кэширование — не роскошь, а средство улучшения быстродействия.
Кэширование — всему голова.
Один — с кэшем, семеро — с браузером.
Как сервер ни убыстряй, а все равно без кэширования упадет.
На мощный процессор надейся, да и с кэшированием не плошай.
Пользователь — не Аллах, кэша не заметит.
Куда ни кинь, всюду — кэширование.
Скрипт кэшированием не испротишь.
После сброса кэша перегревом CPU не хвастают.
Страница — не воробей, вылетит — сразу в кэш.
На сервере — кэш, а в Киеве — браузер.
У семи программистов скрипт без кэширования.
В тихом траффике всплески кэш-промахов водятся.
Любишь скрипты писать, люби и вывод кэшировать.

Так-то
(-;

Powered by POEM™ Engine Copyright © 2002-2005