简体   繁体   English

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

[英]Storing Blobs in Seperate Tables with SQLite?

I am using this SQLite Plugin to benefit from 'unlimited' storage limits as a mobile application. 我正在使用此SQLite插件从移动应用程序的“无限”存储限制中受益。 Basically I have base64 imagedata and need to store this in a database. 基本上我有base64 imagedata ,需要将其存储在数据库中。

In addition, I have some other tables and one Masterdata where the primary keys are stored along with some additional information, such as albumName . 另外,我还有其他一些表和一个Masterdata,其中存储了主键以及一些其他信息,例如albumName

Relational setup with Foreign Keys 使用外键进行关系设置

To cope with the relational aspect of databases, I initially used Foreign Key declarations and created the tables as follows (for simplicity only two tables shown): 为了应付数据库的关系方面,我最初使用外键声明并按如下方式创建表(为简单起见,仅显示两个表):

      // 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)\
        )"
      )

Then, when I wanted to load only the images of a specific album, I run the query: 然后,当我只想加载特定专辑的图像时,我运行查询:

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

This worked fine (everything loads as it should), however I noticed immediately that it gets Slow when dealing with a large dataset. 这个工作正常(一切都应该加载),但是我立即注意到处理大型数据集时它变慢。 This makes sense as base64 strings are quite storage extensive. 这很有意义,因为base64字符串在存储方面相当广泛。

Store Blobs in Separate Tables 将Blob存储在单独的表中

So I read this post , which recommends to consider storing each BLOB in a separate table , if your data includes BLOBs. 因此,我阅读了这篇文章建议您考虑将每个BLOB存储在单独的表中 (如果您的数据包含BLOB)。

I coded this as follows: 我将其编码如下:

// 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)"
); 

and then I insert the data in this table with the query: 然后使用查询将数据插入此表中:

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

Outcome 结果

The outcome is that I noticed a significant increase in the loading time, even when having stored multiple images (thus having multiple tables). 结果是,即使存储了多个图像(因此具有多个表),我也注意到加载时间显着增加。 It looks to me that it makes sense as we can use the Masterdata to filter out the selected album id 's and then only load the images from one table. 在我看来,这很有意义,因为我们可以使用Masterdata筛选出所选专辑id ,然后仅从一张表中加载图像。

My questions are: 我的问题是:

  • Is this a bad, oke, or good practice? 这是坏习惯还是好习惯?
  • Are there disadvantages of having a large number of tables (for example, if I have 1000 images, I will have 1000 tables with this setup) 拥有大量表格是否有缺点(例如,如果我有1000张图像,则使用此设置将有1000张表格)
  • If it is bad practice, what is the better recommended way? 如果不好的做法,最好的推荐方法是什么?

Storing each blob in its own table is definitely not the way to go. 将每个Blob存储在自己的表中绝对不是要走的路。 I think the article is recommending your first approach, which should be fine, except that your query is wrong. 我认为本文建议您采用第一种方法,该方法应该很好,但您的查询错误。

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

This joins one row in Masterdata with every row in ImagesData , even if the ImageData doesn't belong to the Masterdata . 即使ImageData不属于ImagesData ,这也会将Masterdata中的每一行ImagesData 每一行连接Masterdata You need to add a join condition: 您需要添加一个连接条件:

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

Or better yet, use the explicit join syntax: 或更妙的是,使用显式联接语法:

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

Also make sure that Masterdata.id and ImagesData.id have indexes. 还要确保Masterdata.idImagesData.id具有索引。

Well if its image only why not store directly in directory as an image and have the name and hash of that image in database. 好吧,如果仅是其映像,为什么不直接将其作为映像存储在目录中,并在数据库中具有该映像的名称和哈希值。 This will allow u to reduce your load time further. 这将使您进一步减少加载时间。 Hash will let you check in future for if an update has happened on server. 哈希可以让您将来检查服务器上是否发生了更新。 Watsapp and other messengers do that. Watsapp和其他Messenger就是这样做的。

Keeping it in apps protected directories will ensure no one has access. 将其保存在应用程序受保护的目录中将确保没有人可以访问。

If too many files then consider breaking into folders->sub folder->file. 如果文件太多,则考虑分成文件夹->子文件夹->文件。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM