【发布时间】:2010-10-15 03:51:20
【问题描述】:
我在 SQLite 应用程序中有大块,需要以分段方式更新这些块的小段。就像说“使用数据 D 更新 blob B 的字节 X 到 Y”,这可以在其他具有 Blob 操作函数的数据库中完成,但是对于 SQLite,我找不到类似的东西,我被卡住了吗?还是 SQLite 有处理 Blob 的方法?
谢谢。
【问题讨论】:
我在 SQLite 应用程序中有大块,需要以分段方式更新这些块的小段。就像说“使用数据 D 更新 blob B 的字节 X 到 Y”,这可以在其他具有 Blob 操作函数的数据库中完成,但是对于 SQLite,我找不到类似的东西,我被卡住了吗?还是 SQLite 有处理 Blob 的方法?
谢谢。
【问题讨论】:
这不是您问题的直接答案,但我有一些在 SQLite 中使用随机访问(大)blob 的经验,如果可以的话,我建议您不要使用它。原因如下:
Blob 完全打破了 SQL 查询格式。如果您的 blob 数据需要任何类型的处理,它肯定会在某些时候需要过滤。无论你有什么机制来处理 SQL 中的过滤,在这方面都是无用的。
处理包含在数据库中的二进制 blob,而不是原始文件中的二进制数据,这限制了您的选择。您将无法同时从多个进程随机读取和写入数据,这对于文件是可能的。您不能使用任何处理这些数据并且只提供文件 I/O 接口的工具。您不能截断或调整 blob 的大小。文件的用途更加广泛。
将所有内容包含在一个文件中似乎很方便,因为它简化了备份和传输,但使用 blob 的痛苦根本不值得。
因此,作为您的律师,我建议您将 blob 作为原始文件写入文件系统,并仅在数据库中存储对文件名的引用。如果您的 blob 很小并且保证不会增长,请忘记我的建议。
【讨论】:
SQLite 3.x 通过sqlite3_blob_write 函数支持这一点。
int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset)
请注意,此函数是作为 SQLite 3 C/C++ API 的一部分提供的。您需要直接对此进行编程才能使用它。
如果您使用其他更高级别的包装器,例如 System.Data.SQLite,上次我查看时,您将无法访问此函数。
【讨论】:
我非常同意 paniq 所说的一切。使用 BLOB 会大大限制您的选择。
如果您使用 System.Data.SQLite,您将无法真正支持 BLOB。这就是我编写自己的类来处理它们的原因。你可以在这里找到代码:Sample BLOB code
请注意,对于那些敢于使用 BLOB 的人来说,SQLite 有几个潜在的陷阱。主要问题之一是 SQLite 在允许您检查它们的长度之前将整个 BLOB 字段加载到内存中。因此,如果您有大型 BLOB 字段,预计会有很多内存抖动...
【讨论】: