Хранение изображений в PostgreSQL - PullRequest
97 голосов
/ 10 сентября 2008

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

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

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

Ответы [ 6 ]

53 голосов
/ 22 апреля 2012

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

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

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

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

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

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

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

NOTE2: помните, что PostgreSQL имеет только bytea , не имеет Oracle по умолчанию BLOB : «Стандарт SQL определяет (...) BLOB. Формат ввода отличается от bytea , но предоставляемые функции и операторы в основном одинаковы ", Manual .


РЕДАКТИРОВАТЬ 2014 : я не изменил исходный текст выше сегодня (мой ответ был 22 апреля '12, теперь с 14 голосами), Я открываю ответ для ваших изменений ( см. «Режим вики», вы можете редактировать!), для корректура и для обновлений .
Вопрос стабильный (ответ @ Ивана '08 с 19 голосами), пожалуйста, помогите улучшить этот текст.

51 голосов
/ 19 сентября 2008

Re Jcoby's ответ:

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

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

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

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

Я бы сказал наоборот :). Если изображения - это не единственные данные, которые вы храните, не храните их в файловой системе, если в этом нет необходимости. Это такое преимущество, чтобы всегда быть уверенным в согласованности ваших данных и иметь данные «в одном куске» (БД). Кстати, PostgreSQL хорош в сохранении согласованности.

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

26 голосов
/ 10 сентября 2008

В базе данных есть две опции:

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

В прошлом я с большим успехом использовал столбцы bytea, храня изображения размером более 10 ГБ с тысячами строк. Функциональность PG TOAST в значительной степени сводит на нет все преимущества, которые имеют BLOB-объекты. Вам нужно будет включить столбцы метаданных в любом случае для имени файла, типа контента, размеров и т. Д.

20 голосов
/ 01 июня 2015

Быстрое обновление до середины 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, в то время как они все еще существуют в фактической файловой системе, что означает, что вы можете использовать любую файловую систему, которую хотите, и веб-сервер может обслуживать напрямую (кеширование ОС тоже применимо).

14 голосов
/ 10 сентября 2008

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

Оригинал

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

//linuxserver/images/imagexxx.jpg

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

5 голосов
/ 10 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...