使用 SQLite 将 Blob 存储在单独的表中?

Storing Blobs in Seperate Tables with SQLite?

我正在使用这个 SQLite Plugin 作为移动应用程序来享受 'unlimited' 存储限制。基本上我有 base64 imagedata 并且需要将其存储在数据库中。

此外,我还有一些其他 tables 和一个 Masterdata,其中存储了主键以及一些附加信息,例如 albumName.

使用外键建立关系

为了应对数据库的关系方面,我最初使用外键声明并创建了 table 如下(为简单起见,只显示了两个 table):

      // Master Data
      $cordovaSQLite.execute(db, 
      "CREATE TABLE IF NOT EXISTS \
        Masterdata(\
          id TEXT primary key, \
          albumName TEXT, \
          favorite INTEGER\
        )"
      )

      // Images
      $cordovaSQLite.execute(db, 
      "CREATE TABLE IF NOT EXISTS \
        ImagesData(\
          id TEXT, \
          data BLOB, \
          FOREIGN KEY(id) REFERENCES Masterdata(id)\
        )"
      )

然后,当我只想加载特定相册的图像时,我 运行 查询:

SELECT Masterdata.id, ImagesData.data FROM ImagesData, Masterdata WHERE Masterdata.album = (?) ["Some album name"]

这工作正常(一切正常加载),但我立即注意到它在处理大型数据集时变慢了。这是有道理的,因为 base64 字符串的存储空间很大。

将 Blob 存储在单独的表中

所以我读了这个 post 如果您的数据包含 BLOB,建议考虑将每个 BLOB 存储在单独的 table 中。

我编码如下:

// tableName in the form of 'id'_imagesData
// 'id' is stored also in Masterdata

$cordovaSQLite.execute(db, 
      "CREATE TABLE IF NOT EXISTS "
        + tableName + "(id integer, data BLOB)"
); 

然后我在这个 table 中插入数据并查询:

"INSERT INTO " + tableName + " (id, data) VALUES (?,?)", parameters
// parameters = [0, base64_imageData_Str]

结果

结果是我注意到加载时间显着增加,即使存储了多个图像(因此有多个 tables)。在我看来,这是有道理的,因为我们可以使用 Masterdata 过滤掉所选相册 id,然后只加载一张 table.

中的图像

我的问题是:

将每个 blob 存储在其自己的 table 中绝对 不是 要走的路。我认为这篇文章是在推荐你的第一种方法,应该没问题,只是你的查询是错误的。

SELECT Masterdata.id, ImagesData.data
FROM ImagesData, Masterdata
WHERE Masterdata.album = 'some name'

这将 Masterdata 中的一行与 ImagesData 中的 每一行 连接起来,即使 ImageData 不属于 Masterdata。您需要添加一个连接条件:

...
WHERE Masterdata.album = 'some name' AND ImageData.id = Masterdata.id

或者更好的是,使用显式连接语法:

SELECT Masterdata.id, ImagesData.data
FROM Masterdata
INNER JOIN ImagesData ON ImagesData.id = Masterdata.id
WHERE Masterdata.album = 'some name'

还要确保 Masterdata.idImagesData.id 有索引。

好吧,如果它的图像只是图像,为什么不直接将图像作为图像存储在目录中,并在数据库中包含该图像的名称和哈希值。这将使您能够进一步减少加载时间。 哈希将让您将来检查服务器上是否发生了更新。 Watsapp 和其他 Messenger 就是这样做的。

将其保存在受保护的应用程序目录中将确保没有人可以访问。

如果文件太多则考虑分成文件夹->子文件夹->文件。

希望对您有所帮助。