Размер большого двоичного объекта Firebird составляет всего 32 КБ?

У меня есть база данных Firebird с полем blob для изображений в формате base64. Если я пытаюсь загрузить закодированное изображение размером более 32 КБ, это дает мне исключение:

org.firebirdsql.jdbc.FBSQLException: исключение GDS. 335544569. Динамическая ошибка SQL Код ошибки SQL = -104 Сообщение для кода 336397331 не найдено.

Это означает, что строковый литерал с X байтов превышает максимальную длину Y байтов. Действительно ли большой двоичный объект Firebird такой маленький, и мне нужно, например, изменить свою БД для mySQL? У меня нет ни времени, ни знаний php, чтобы создавать back-end api для картинок.

BLOB-объекты могут быть любой длины, но BLOB-объекты НЕ являются строковыми литералами. Похоже, вы используете сращивание строк, которое является хрупким (вы не можете быть уверены в представлении типов данных, таких как даты/время/поплавки) и опасными (инъекции). Это ненормально. Используйте параметры. bobby-tables.com/php

Arioch 'The 15.12.2020 09:26

Кроме того, зачем раздувать изображения до больших данных base64? Просто сохраните их как есть, в двоичном виде.

Arioch 'The 15.12.2020 09:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
856
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не вставляйте строковые литералы в BLOB. Используйте параметризованные запросы и помещайте данные в BLOB через них. В этом случае они могут оставить не менее 2 гигабайт.

https://www.firebirdsql.org/file/documentation/drivers_documentation/java/3.0.0/docs/org/firebirdsql/jdbc/FBBlob.html

Как добавить изображение блоба FIrebird в php?

pdo напрямую вставлять изображение в базу данных - всегда вставляя BLOB - 0B

Ответ принят как подходящий

Большие двоичные объекты в Firebird могут быть намного больше 32 килобайт. В зависимости от размера страницы базы данных максимальный размер одного большого двоичного объекта может достигать чуть менее 4 ГБ (размер страницы 4096) или более 128 ГБ (размер страницы 16384).

Проблема в том, что, судя по всему, вы создали запросы, объединяя значения в строку запроса вместо использования параметров. Объединение значений в строку запроса небезопасно (оно делает вас уязвимым для SQL-инъекций), но в этом случае вы также достигаете жесткого ограничения. В Firebird строковые литералы ограничены 32 килобайтами (или — начиная с Firebird 3 — 64 килобайтами (фактически 64 килобайта — 3) при назначении большому двоичному объекту).

Если вы хотите присвоить большие значения, вы должны использовать подготовленный оператор с параметрами. Например (ПРИМЕЧАНИЕ: я публикую код Java, потому что ошибка, которую вы разместили в своем вопросе, создается Jaybird, драйвером JDBC Firebird (для Java)):

try (var pstmt = connection.prepareStatement("insert into images (filename, blobdata) values (?, ?)")) {
    pstmt.setString(1, "filename.jpg");
    pstmt.setBinaryStream(2, someInputStreamForTheData);
    // or: pstmt.setBytes(2, fileBytes);
    pstmt.executeUpdate();
}

Кроме того, сохранение изображений в кодировке base64 в большом двоичном объекте (при условии, что BLOB SUB_TYPE BINARY, а не BLOB SUB_TYPE TEXT) не имеет для меня особого смысла, изображения представляют собой двоичные данные, а большие двоичные объекты предназначены для сохранения двоичных данных. Использование base64 вводит ненужные накладные расходы на хранение (1 дополнительный байт на каждые 3 байта данных).

Да, я пытался реализовать это в своем приложении для Android, но похоже, что «setBinartStream» еще не реализован, поскольку у Android нет официально поддерживаемой версии, а драйвер достаточно старый. Но это не предмет данного вопроса.

ezh 16.12.2020 16:36

@ezh Вы не должны подключаться напрямую к базе данных Firebird с Android (или любой удаленной базы данных в этом отношении), более целесообразным подходом является создание REST API на Java или другом языке и заставить ваше приложение Android общаться с этим REST API.

Mark Rotteveel 17.12.2020 17:57

Да, я сейчас разрабатываю API для этого :)

ezh 17.12.2020 22:20

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