Зберігання зображень у PostgreSQL


111

Гаразд, тому я працюю над додатком, який використовуватиме Linux Back-End під управлінням PostgreSQL для подання зображень у вікно Windows із переднім кінцем, записаним на C # .NET, хоча передній край навряд чи має значення. Моє запитання:

  • Який найкращий спосіб впоратися із збереженням зображень у Postgres?

Зображення мають приблизно 4-6 мегапікселів кожен, і ми зберігаємо більше 3000. Це також може бути добре відзначити: це не веб-додаток, мабуть, приблизно два передні частини, що мають доступ до бази даних одразу.

Відповіді:


64

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

Нам потрібно певне розмежування між "оригінальним зображенням" та "обробленим зображенням", як мініатюра.

Як сказано у відповіді Джокобі, є два варіанти, тож рекомендую:

  • використовувати blob (Binary Large OBject): для зберігання оригінальних зображень, за вашим столом. Дивіться відповідь Івана (немає проблем із резервним копіюванням крапок!), Додаткові модулі PostgreSQL, що постачаються , інструкції та ін.

  • використовувати окрему базу даних з DBlink : для зберігання оригінальних зображень, для іншої (уніфікованої / спеціалізованої) бази даних. У цьому випадку, я вважаю за краще BYTEA , але пляма поруч те ж саме. Розділення бази даних - найкращий спосіб для "уніфікованого веб-сервісу зображень".

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

ПРИМІТКА1: сьогодні використання "подвійних рішень" (база даних + файлова система) застаріла (!). Є багато переваг використання "тільки бази даних" замість подвійного. PostgreSQL мають порівнянну продуктивність та хороші інструменти для експорту / імпорту / введення / виводу.

ПРИМІТКА2: пам’ятайте, що PostgreSQL має лише байт , не має BLOB Oracle за замовчуванням : "Стандарт SQL визначає (...) BLOB. Формат вводу відрізняється від bytea, але надані функції та оператори в основному однакові", Посібник .


РЕДАКТИРУЙТЕ 2014 : Я сьогодні не змінив початковий текст (моя відповідь - 22 квітня 12, зараз - 14 голосів), я відкриваю відповідь на ваші зміни (див. "Режим Wiki", ви можете редагувати!), Для коректури і для оновлень .
Питання стабільне (@08 відповідь Іванса з 19 голосами), будь ласка, допоможіть покращити цей текст.


2
Що таке посилання на "... використання" подвійних рішень "(база даних + файлова система) застаріло ..."?
dangel

Деякі новини 2019 року! З 2018 року PostgREST підтримує прямий вихід bytea в Інтернет. Дивіться цей простий конфігуратор NGINX, щоб ним користуватися. Дивіться Посібник PostgREST про двійковий вихід
Пітер Краусс

52

Відповідь re jcoby:

bytea є "нормальним" стовпцем, також означає, що значення повністю читається в пам'яті, коли ви отримуєте його. Краплі, навпаки, можна перетікати в stdout. Це допомагає зменшити слід пам'яті сервера. Особливо, коли ви зберігаєте 4-6 MPix-зображень.

Немає проблем із резервними копіями крапель. pg_dump надає можливість "-b" включати великі об'єкти в резервну копію.

Отже, я вважаю за краще використовувати pg_lo_ *, ви можете здогадатися.

Відповідь Кріса Еріксона:

Я б сказав протилежне :). Якщо зображення - не єдині дані, які ви зберігаєте, не зберігайте їх у файловій системі, якщо ви абсолютно не повинні. Така користь - завжди бути впевненим у послідовності даних та мати дані "в єдине ціле" (БД). До речі, PostgreSQL чудово допомагає зберігати послідовність.

Однак, правда, реальність часто є занадто вимогливою до продуктивності ;-), і вона підштовхує вас до обслуговування бінарних файлів з файлової системи. Але навіть тоді я схильний використовувати БД як "головне" сховище для бінарних файлів, при цьому всі інші відносини послідовно пов'язані, забезпечуючи деякий механізм кешування на основі файлової системи для оптимізації продуктивності.


14
Ви вважаєте, що через 10 років ваші бали все ще дійсні? Будь-які оновлення з тих пір?
Левентунвер

3
@leventunver Ні, очок не дотримуватися. Наприклад, перший про BYTEAте, що це "звичайний" стовпець. Postgres протягом багатьох років підтримує потокове передавання до / з BYTEAстовпців, що означає, що вам не потрібно зберігати вміст у пам'яті перед тим, як зберігати його в db.
олігофрен

29

У базі даних є два варіанти:

  • bytea. Зберігає дані у стовпці, експортованому як частина резервної копії. Використовує стандартні функції бази даних для збереження та отримання. Рекомендовано для ваших потреб.
  • краплі. Зберігає дані зовні, зазвичай не експортується як частина резервної копії. Потрібні спеціальні функції бази даних для збереження та отримання.

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


1
10 Гб - це не так багато :-( Я шукаю рішення щодо
туберкульозу

2
@ValentinHeinitz Що стосується туберкульозу, ванільна Postgres бореться навіть із меншими текстовими стовпцями.
судо

23

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


1
Дякую .. Чи надають іноземні обгортки даних (file_fdw) доступ для запису зображень? Я хочу зберігати зображення у FileSystem та її метаданих у Postgresql, але я також повинен підтримувати послідовність. Чи є у вас детальне рішення? Чи доступні інші розширення? Мультикорну потрібен пітон, і я вважаю за краще робити це без використання Python ..
Jay Khatwani

1
Так, вони мають доступ до запису. Вони повністю відповідають / в обох напрямках. І ні, я не знаю рівноправного рішення, яке може зробити це без пітона.
Кеніякорн Кецомбут

18

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

Оригінальний

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

//linuxserver/images/imagexxx.jpg

то, можливо, ви можете швидко налаштувати веб-сервер і зберігати веб-адреси в базі даних (як і локальний шлях). У той час як бази даних можуть обробляти зображення LOB та 3000 зображень (4-6 мегапікселів, припускаючи зображення 500K). 1,5 Гіга - це не так багато файлових систем простору, які значно краще розроблені для зберігання великих файлів, ніж є база даних.


15
Але ви повинні придумати спосіб розподілу файлів у кількох каталогах. Файлові системи не такі вже й хороші в тому, щоб зберігати мільйон файлів в одному каталозі (насправді десять тисяч - це вже проблема)
a_horse_with_no_name

1
Не відповідає на початкове запитання. Я особисто хочу зберігати зображення в Postgres лише тому, що хочу, щоб SQL був моїм шаром абстракції, а також не хочу керувати файлами в моїй файловій системі ext4.
судо

Я конфліктую, це не відповідає на питання, але я його схвалив, тому що це краща відповідь, ніж відповідь на питання.
Ендрю Карр

6

Спробуйте це . Я використовую формат Big Object Binary (LOB) для зберігання згенерованих PDF-документів, частина яких розміром 10+ Мб, у базі даних, і це чудово працювало.


2

Якщо ваші зображення невеликі, подумайте про їх збереження як base64 у простому текстовому полі.

Причина полягає в тому, що в той час як base64 має накладні витрати на 33%, стискання в основному проходить. (Див. Який простір для кодування Base64? ) Ваша база даних буде більшою, але пакетів, які ваш веб-сервер надсилає клієнту, не буде. У html ви можете вбудувати base64 в тег <img src = "">, який, можливо, спростить ваш додаток, оскільки вам не доведеться подавати зображення як двійкові в окремому завантаженні браузера. Обробка зображень у вигляді тексту також спрощує речі, коли вам доведеться надсилати / отримувати json, який не дуже добре обробляє двійкові файли.

Так, я розумію, що ви можете зберігати бінарне в базі даних і перетворювати його в / з тексту під час входу та виходу з бази даних, але іноді ORM створює проблеми. Це може бути простіше просто розглянути його як прямий текст, як і всі інші ваші поля.

Це, безумовно, правильний спосіб обробки ескізів.

(Образи ОП не маленькі, тому це насправді не є відповіддю на його запитання.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.