Firebird 的 blob 大小只有 32kb 吗?
Is Firebird's blob size is only 32kb?
我有 Firebird 数据库,其中包含 base64 格式图片的 blob 字段。如果我尝试上传大小超过 32kb 的编码图片,它会出现异常:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
No message for code 336397331 found.
这意味着具有X字节的字符串文字超过了Y字节的最大长度。 Firebird 的 blob 真的那么小吗?例如,我需要为 mySQL 更改我的数据库?我既没有时间也没有 php 知识来为图片创建后端 api。
不要将字符串文字插入 BLOB。使用参数化查询并通过它们将数据放入 BLOB。在这种情况下,他们至少可以保留 2 GB。
pdo insert image into database directly - always inserting BLOB - 0B
Firebird 中的 Blob 可以远大于 32 KB。根据数据库的页面大小,maximum size of a single blob 可以达到略小于 4GB(页面大小 4096)或超过 128GB(页面大小 16384)。
问题是 - 听起来 - 您是通过将值连接到查询字符串而不是使用参数来构造查询的。将值连接到查询字符串中是不安全的(它使您容易受到 SQL 注入的攻击),但在这种情况下,您也会遇到硬限制。在 Firebird 中,字符串文字被限制为 32 KB(或者 - 自 Firebird 3 - 64 KB(实际上是 64kb - 3)分配给一个 blob 时)。
如果要分配更大的值,则必须使用带参数的准备语句。例如(注意:我正在发布 Java 代码,因为您在问题中发布的错误是由 Jaybird,Firebird 的 JDBC 驱动程序(针对 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 中(假设 BLOB SUB_TYPE BINARY
,而不是 BLOB SUB_TYPE TEXT
)对我来说意义不大,图像是二进制数据,而 blob 旨在保存二进制数据。使用 base64 引入了不必要的存储开销(每 3 个字节的数据增加 1 个字节)。
我有 Firebird 数据库,其中包含 base64 格式图片的 blob 字段。如果我尝试上传大小超过 32kb 的编码图片,它会出现异常:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error SQL error code = -104 No message for code 336397331 found.
这意味着具有X字节的字符串文字超过了Y字节的最大长度。 Firebird 的 blob 真的那么小吗?例如,我需要为 mySQL 更改我的数据库?我既没有时间也没有 php 知识来为图片创建后端 api。
不要将字符串文字插入 BLOB。使用参数化查询并通过它们将数据放入 BLOB。在这种情况下,他们至少可以保留 2 GB。
pdo insert image into database directly - always inserting BLOB - 0B
Firebird 中的 Blob 可以远大于 32 KB。根据数据库的页面大小,maximum size of a single blob 可以达到略小于 4GB(页面大小 4096)或超过 128GB(页面大小 16384)。
问题是 - 听起来 - 您是通过将值连接到查询字符串而不是使用参数来构造查询的。将值连接到查询字符串中是不安全的(它使您容易受到 SQL 注入的攻击),但在这种情况下,您也会遇到硬限制。在 Firebird 中,字符串文字被限制为 32 KB(或者 - 自 Firebird 3 - 64 KB(实际上是 64kb - 3)分配给一个 blob 时)。
如果要分配更大的值,则必须使用带参数的准备语句。例如(注意:我正在发布 Java 代码,因为您在问题中发布的错误是由 Jaybird,Firebird 的 JDBC 驱动程序(针对 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 中(假设 BLOB SUB_TYPE BINARY
,而不是 BLOB SUB_TYPE TEXT
)对我来说意义不大,图像是二进制数据,而 blob 旨在保存二进制数据。使用 base64 引入了不必要的存储开销(每 3 个字节的数据增加 1 个字节)。