Сохранение изображений в PostgreSQL

Вопрос:

Хорошо, поэтому я работаю над приложением, которое будет использовать Linux-сервер под управлением PostgreSQL для обслуживания изображений в окне Windows с интерфейсом, написанным на С#.NET, хотя интерфейс не должен иметь большого значения. Мой вопрос:

  • Каков наилучший способ хранения изображений в Postgres?

Изображения составляют около 4-6 мегапикселей каждый, и мы сохраняем до 3000. Также неплохо было бы отметить: это не веб-приложение, в котором будет почти два фронтальных доступа к базе данных сразу.

Ответ №1

Обновление до 2012 года, когда мы увидим, что размеры и количество изображений растут и растут во всех приложениях…

Нам нужно провести различие между “исходным изображением” и “обработанным изображением”, например, миниатюрой.

Как говорит ответ Jcoby, есть два варианта, поэтому я рекомендую:

  • используйте blob (Binary Large OBject): для хранения оригинального изображения, на вашем столе. См. ответ ивана (нет проблем с резервным копированием больших двоичных объектов!), дополнительные поставляемые модули PostgreSQL, инструкции и т.д.

  • используйте отдельную базу данных с DBlink: для хранения исходного изображения, в другой (унифицированной/специализированной) базе данных. В этом случае я предпочитаю байту, но капля почти такая же. Разделение базы данных – лучший способ для “унифицированного веб-сервиса изображений”.

  • Используйте bytea (BYTE Array): для кэширования миниатюр изображений. Кэшируйте небольшие изображения, чтобы быстро отправлять их в веб-браузер (чтобы избежать проблем с рендерингом) и сократить обработку на сервере. Кэшируйте также важные метаданные, такие как ширина и высота. Кэширование базы данных – самый простой способ, но проверьте свои потребности и настройки сервера (например, модули Apache): хранить миниатюры в файловой системе может быть лучше, сравните производительность. Помните, что это (унифицированный) веб-сервис, который можно хранить в отдельной базе данных (без резервных копий), обслуживающей множество таблиц. См. также Руководство по двоичным типам данных PostgreSQL, тесты со столбцом bytea и т.д.

ПРИМЕЧАНИЕ 1: сегодня использование “двойных решений” (база данных + файловая система) не рекомендуется (!). Есть много преимуществ использования “только базы данных” вместо двойного. PostgreSQL обладает сопоставимой производительностью и хорошими инструментами для экспорта/импорта/ввода/вывода.

ПРИМЕЧАНИЕ 2. Помните, что PostgreSQL имеет только bytea, но не имеет Oracle BLOB по умолчанию: “Стандарт SQL определяет (…) BLOB. Формат ввода отличается от bytea, но предоставляемые функции и операторы в основном одинаковы”,Руководство.


ОБНОВЛЕНИЕ 2014: я не изменил исходный текст выше сегодня (мой ответ был 22 апреля ’12, теперь с 14 голосами), я открываю ответ для ваших изменений (см. “Режим Wiki”, вы можете изменить!), для корректуры и для обновлений.
Вопрос стабильный (ответ @Ivans ’08 с 19 голосами), пожалуйста, помогите улучшить этот текст.

Ответ №2

Re jcoby answer:

bytea, являющийся “нормальным” столбцом, также означает, что значение считывается полностью в память при его извлечении. Blobs, напротив, вы можете передавать в stdout. Это помогает уменьшить объем памяти сервера. Особенно, когда вы сохраняете 4-6 изображений MPix.

Нет проблем с резервным копированием. pg_dump предоставляет опцию -b для включения больших объектов в резервную копию.

Итак, я предпочитаю использовать pg_lo_ *, вы можете догадаться.

Ответ Криса Эриксона:

Я бы сказал наоборот:). Когда изображения не являются единственными данными, которые вы храните, не храните их в файловой системе, если вам не нужно. Такое преимущество всегда быть в курсе вашей согласованности данных и иметь данные “в одном куске” (БД). BTW, PostgreSQL отлично подходит для сохранения согласованности.

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

Ответ №3

В базе данных есть два варианта:

  • BYTEA. Сохраняет данные в столбце, экспортированном как часть резервной копии. Использует стандартные функции базы данных для сохранения и извлечения. Рекомендуется для ваших нужд.
  • сгустки. Хранит данные извне, обычно не экспортируется как часть резервной копии. Требуется специальные функции базы данных для сохранения и извлечения.

Я использовал столбцы bytea с большим успехом в прошлом, сохраняя 10 + gb изображений с тысячами строк. Функциональность PG TOAST в значительной степени отрицает любое преимущество, которое имеют blobs. Вам нужно будет включать столбцы метаданных в любом случае для имени файла, типа содержимого, размеров и т.д.

Ответ №4

Быстрое обновление до середины 2015 года:

Вы можете использовать интерфейс Postgres Foreign Data, чтобы хранить файлы в более подходящей базе данных. Например, поместите файлы в GridFS, которая является частью MongoDB. Тогда используйте
https://github.com/EnterpriseDB/mongo_fdw
чтобы получить доступ к нему в Postgres.

Это имеет то преимущество, что вы можете получить доступ/читать/писать/резервировать его в Postrgres и MongoDB, в зависимости от того, что дает вам больше гибкости.

Существуют также сторонние оболочки данных для файловых систем:
https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers

В качестве примера вы можете использовать это:
https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html
(см. здесь для краткого примера использования)

Это дает вам преимущество согласованности (все связанные файлы обязательно присутствуют) и всех других ACID, в то время как они все еще существуют в фактической файловой системе, что означает, что вы можете использовать любую файловую систему, которую хотите, и веб-сервер может обслуживать их напрямую ( Кеширование ОС тоже применимо).

Ответ №5

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

Оригинал

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

//linuxserver/images/imagexxx.jpg

тогда, возможно, вы сможете быстро настроить веб-сервер и сохранить URL-адреса веб-сайтов в базе данных (а также локальный путь). В то время как базы данных могут обрабатывать LOB и 3000 изображений (4-6 мегапикселей, при условии 500K изображения), 1,5 гигабайта не так много, файловые системы пространства гораздо лучше разработаны для хранения больших файлов, чем база данных.

Ответ №6

Попробуйте это. Я использую формат больших объектов двоичных файлов (LOB) для хранения сгенерированных документов PDF, некоторые из которых имеют размер 10+ МБ, в базе данных, и это прекрасно работает.

Ответ №7

Если ваши изображения маленькие, попробуйте сохранить их как base64 в текстовом поле.

Причина в том, что в то время как у base64 накладные расходы составляют 33%, при этом сжатие в основном исчезает. (См. Какое пространство занимает место в кодировке Base64?) Ваша база данных будет больше, но пакетов, отправляемых вашим веб-сервером клиенту, не будет. В html вы можете встроить base64 в тег & lt; img src= “”>, что может упростить ваше приложение, поскольку вам не нужно будет обрабатывать изображения в виде двоичного файла в отдельной выборке браузера. Обработка изображений как текста также упрощает процесс отправки/получения json, который не очень хорошо обрабатывает двоичные файлы.

Да, я понимаю, что вы можете хранить двоичный файл в базе данных и преобразовывать его в/из текста при входе и выходе из базы данных, но иногда ORM создают трудности. Может быть проще воспринимать его как простой текст, как и все остальные поля.

Это определенно правильный способ обработки миниатюр.

(OP изображения не маленькие, так что это не совсем ответ на его вопрос.)

Оцените статью
TechArks.Ru
Добавить комментарий