PostgreSQL: BYTEA против OID+большой объект?

Я запустил приложение с Hibernate 3.2 и PostgreSQL 8.4. У меня есть некоторые поля byte[], которые были сопоставлены как @Basic (= PG bytea), а другие — как @Lob (=большой объект PG). Почему несоответствие? Потому что я был новичком в Hibernate.

Теперь эти поля имеют максимальный размер 4 КБ (но в среднем 2-3 КБ). В документации PostgreSQL упоминается, что LO хороши, когда поля большие, но я не понял, что означает «большой».

Я обновился до PostgreSQL 9.0 с Hibernate 3.6 и застрял, чтобы изменить аннотацию на @Type(type="org.hibernate.type.PrimitiveByteArrayBlobType"). Эта ошибка привела к потенциальной проблеме совместимости, и в конце концов я обнаружил, что с большими объектами сложнее иметь дело по сравнению с обычным полем.

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

Есть ли хорошие тесты производительности обоих из них? Кто-нибудь менял и увидел разницу?


person malaverdiere    schedule 10.01.2011    source источник
comment
Предостережение для больших объектов: поскольку все фрагменты используют одну и ту же системную таблицу, ограничение на общий объем, который вы можете хранить, ниже, чем для bytea.   -  person OrangeDog    schedule 05.03.2019
comment
В зависимости от того, что это такое, lo_compat_privileges может решить проблемы совместимости.   -  person OrangeDog    schedule 05.03.2019


Ответы (4)


В основном есть случаи, когда каждый имеет смысл. bytea проще и обычно предпочтительнее. Клиентские библиотеки дают вам декодирование, так что это не проблема.

Однако у LOB есть некоторые удобные функции, такие как возможность поиска внутри них и обработка LOB как потока байтов, а не массива байтов.

«Большой» означает «Достаточно большой, чтобы не отправлять его клиенту сразу». Технически bytea ограничена сжатием 1 ГБ, а lob ограничен сжатием 2 ГБ, но на самом деле вы все равно сначала достигаете другого ограничения. Если он достаточно большой, вы не хотите, чтобы он находился непосредственно в вашем результирующем наборе, и вы не хотите сразу отправлять его клиенту, используйте LOB.

person Chris Travers    schedule 05.09.2012
comment
Я предполагаю, что большие объекты сжаты так же, как столбцы TOASTed bytea? - person OrangeDog; 05.03.2019

Но меня беспокоит, что поля bytea закодированы в шестнадцатеричном формате

ввод bytea может быть в шестнадцатеричном или escape-формате, это ваш выбор. Хранение будет таким же. Начиная с версии 9.0, выходные данные по умолчанию — шестнадцатеричные, но вы можете изменить это, отредактировав параметр bytea_output.

Я не видел никаких эталонов.

person Frank Heikens    schedule 10.01.2011
comment
Кроме того, он не хранится в шестнадцатеричном формате, и я думаю, что libpq (и, возможно, даже протокол) имеет интерфейс для двоичной передачи обоих. - person Chris Travers; 16.11.2013

У меня нет под рукой сравнения больших объектов и bytea, но обратите внимание, что переход на шестнадцатеричный формат вывода в 9.0 был сделан еще и потому, что он быстрее, чем предыдущая пользовательская кодировка. Что касается текстового кодирования двоичных данных, вы, вероятно, не станете намного быстрее, чем сейчас.

Если этого недостаточно для вас, вы можете рассмотреть возможность использования бинарного протокола между клиентом и сервером PostgreSQL. Затем вы в основном получаете материал прямо с диска, как большие объекты. Я не знаю, поддерживает ли это PostgreSQL JDBC, но быстрый поиск показывает, что нет.

person Peter Eisentraut    schedule 10.01.2011

tl;dr Используйте bytea, если вам не нужна потоковая передача.

bytea представляет собой последовательность байтов и работает как любое другое значение.

Большой объект разбит на несколько строк. Это позволяет вам искать, читать и записывать большие объекты, такие как файл ОС. Вы можете работать с ними, не загружая все сразу в память.

Однако у крупных объектов есть и недостатки:

  1. Единственная таблица больших объектов для каждой базы данных.

  2. Крупные объекты не удаляются автоматически при удалении записи владельца. (Технически на большой объект могут ссылаться несколько записей.) См. функцию lo_manage в модуле lo.

  3. Поскольку имеется только одна таблица, права доступа к большим объектам должны обрабатываться запись за записью.

  4. Потоковая передача сложна и меньше поддерживается клиентскими драйверами, чем простой bytea.

  5. Это часть системной схемы, поэтому вы не можете контролировать такие параметры, как разбиение на разделы и табличные пространства.

По вместимости особой разницы нет. bytea ограничен 1 ГБ; размер больших объектов ограничен 2 ГБ. Если 1 ГБ слишком ограничен, возможно, 2 ГБ тоже.

Рискну предположить, что в 93% реальных случаев использования больших объектов лучше использовать bytea.

person Paul Draper    schedule 06.01.2021