Есть ли проблемы с производительностью при хранении файлов в PostgreSQL?

Можно ли хранить такие файлы, как HTML-страницы, изображения, PDF и т. Д. В таблице в PostgreSQL, или это медленно? Я прочитал несколько статей о том, что это не рекомендуется, но я не знаю, правда ли это.

А что лучше использовать, хранить как BLOB (он хранится в файле, верно?) или в столбце с bytea тип?

2 ответа

Решение

У вас есть в основном два варианта. Вы можете хранить данные прямо в строке или использовать объект большого объекта. Поскольку PostgreSQL теперь использует нечто, называемое TOAST, для перемещения больших полей из таблицы, не должно быть снижения производительности, связанного с непосредственным хранением больших данных в строке. Размер поля не может превышать 1 ГБ. Если это слишком ограничено или если вы хотите потоковый API, вы можете использовать средство больших объектов, которое дает вам что-то более похожее на файловые дескрипторы в базе данных. Вы сохраняете LO ID в своем столбце и можете читать и писать с этого ID.

Лично я бы посоветовал вам избегать большого объекта, если он вам абсолютно не нужен. С TOAST большинство вариантов использования покрываются просто использованием базы данных так, как вы ожидаете. С большими объектами вы берете на себя дополнительное бремя обслуживания, потому что вам нужно отслеживать идентификаторы LO, которые вы использовали, и обязательно отсоединять их, когда они больше не используются (но не раньше), или они будут сидеть в вашем каталог данных занимает пространство навсегда. Есть также много объектов, которые имеют исключительное поведение вокруг них, детали которых избегают меня, потому что я никогда не использую их.

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

Тип BLOB (LO) хранит данные в кусках по 2 КБ в стандартных страницах кучи PostgreSQL, размер которых по умолчанию равен 8 КБ. Они не хранятся как независимые, связные файлы в файловой системе - например, вы не сможете найти файл, выполнить побайтовое сравнение и ожидать, что он будет таким же, как исходные данные файла, которые вы загружен в базу данных, так как есть также заголовки и структуры страниц кучи Postgres, которые разграничивают фрагменты.

Вам следует избегать использования интерфейса больших объектов (LO), если вашему приложению необходимо будет часто обновлять двоичные данные, особенно если это связано с большим количеством небольших записей с произвольным доступом, что обусловлено тем, как PostgreSQL реализует управление параллелизмом (MVCC). может привести к взрыву в объеме используемого дискового пространства, пока вы VACUUM базы данных. Тот же результат, вероятно, также применим к данным, хранящимся в строке в столбце с типом bytea или даже TOAST'd.

Однако, если ваши данные следуют шаблону "запись-один-чтение-много" (например, загрузите изображение в формате PNG и никогда не изменяйте его впоследствии), это должно подойти с точки зрения использования диска.

Посмотрите эту ветку списка рассылки pgsql-general для дальнейшего обсуждения.

Другие вопросы по тегам