为什么建议将图像存储在磁盘而不是Realm中 [英] Why is it recommended practice to store images on disk rather than in a Realm

查看:129
本文介绍了为什么建议将图像存储在磁盘而不是Realm中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Realm作为我的应用程序的数据库解决方案。我的图像需要持久存储能力,所以我可以在离线时加载它们。我还需要一个缓存,所以我可以从那里加载图像,而不是每次单元格绘制它时从API中获取它们。我的第一个想法是,如果我要将Realm中的图像存储为NSData,那么Realm数据库可以很好地服务这两个函数。但我在SE上找到了两个答案(这里这里)如果您有许多大图像会改变,建议不要这样做经常。相反,他们建议将图像保存到磁盘,然后将URL存储到Realm中的那些图像。

I am using Realm as the database solution for my app. I need persistent storage ability for my images so I can load them when offline. I also need a cache so I can load the images from there rather than fetching them from the API each time a cell draws them. My first thought was that a Realm database could serve both of these functions just fine if I were to store the images in Realm as NSData. But I have found two answers on SE (here and here) that recommend not doing this if you have many images of a largish size that will change often. Instead they recommend saving the images to disk, and then storing the URL to those images in Realm.

我的问题是为什么这是最佳实践?与上述相关的答案没有给出理由,除非说你最终得到了一个膨胀的数据库。但为什么这是一个问题呢?在我的数据库中拥有大量图像与在磁盘上拥有大量图像之间有什么区别?

My question is why is this best practice? The answers linked to above don't give reasons why except to say that you end up with a bloated database. But why is that a problem? What is the difference between a having lots of images in my database vs having lots of images on disk?

速度问题是什么?如果是这样,应用程序是否能够从磁盘访问映像以便能够从Realm等数据库解决方案访问它?

Is it a speed issue? If so, is there a marked speed difference in an app being able to access an image from disk to being able to access it from a database solution like Realm?

感谢提前。

推荐答案

这不仅仅是本地化到Realm的问题。我记得Core Data也给出了同样的建议。

This isn't really just a problem localised to Realm. I remember the same advice being given with Core Data too.

我猜的主要原因是为什么在数据库中存储大型二进制数据不是建议是因为你没有获得任何东西,实际上会失去比你更多的东西。

I'm guessing the main reason above all else as to why storing large binary data in a database isn't recommended is because 'You don't gain anything, and actually stand to lose more than you otherwise would'.

使用Core Data(即由SQLite支持的数据库),当您从SQLite执行读取时,数据将被复制到内存中,实际上会受到性能影响。如果它是大量数据,那么这是完全不可接受的。

With Core Data (i.e. databases backed by SQLite), you'll actually take a performance hit as the data will be copied into memory when you perform the read from SQLite. If it's a large amount of data, then this is wholly unacceptable.

至少使用Realm,因为它使用零拷贝,内存映射机制,所以你将获得 NSData 直接从Realm文件映射,但是再次,这绝对没有什么不同,如果您只是从磁盘本身加载图像文件。

With Realm at least, since it uses a zero-copy, memory-mapped mechanism, you'll be provided with the NSData mapped straight from the Realm file, but then again, this is absolutely no different than if you simply loaded the image file from disk itself.

Realm中的一个主要问题是当您经常开始更改图像时。在处理跨线程更改数据时,Realm实际上使用内部快照机制,但这实际上意味着在操作期间,整个数据集可能会定期在磁盘上复制(以确保线程安全)。如果数据集包含大量二进制数据,那么这些数据集也会重复(这也可能意味着性能下降)。发生这种情况时,磁盘上Realm文件的大小将增加以容纳快照,但是当操作完成并删除快照时,文件将不会缩小回原始大小。这是因为回收磁盘空间将是一个代价高昂的性能损失,并且由于很可能再次需要空间(即通过另一个大的快照操作),因此先发制人地执行(因此膨胀)似乎效率低下。

Where this becomes a major problem in Realm is when you start changing the image often. Realm actually uses an internal snapshotting mechanism when working with changing data across threads, but that essentially means that during operation, entire sets of data might be periodically duplicated on-disk (To ensure thread-safety). If the data sets include large blobs of binary data, these will get duplicated too (Which might also mean a performance hit as well). When this happens, the size of the Realm file on disk will be increased to accomodate the snapshots, but when the operation completes and the snapshots are deleted, the file will not shrink back to it's original size. This is because reclaiming that disk space would be a costly performance hit, and since it's easily possible the space could be needed again (i.e. by another large snapshotting operation), it seems inefficient to pre-emptively do (hence the 'bloat').

如有必要,可以手动执行操作以回收此磁盘空间,但通常建议的方法是优化代码以最大限度地减少这种情况。

It's possible to manually perform an operation to reclaim this disk space if necessary, but the generally recommended approach is to optimise your code to minimise this from happening in the first place.

所以,总而言之,虽然你完全可以将大数据blob保存到数据库,但随着时间的推移,它可能会导致性能下降和文件大小膨胀你本可以避免的。这些类型的数据库旨在帮助将少量数据转换为可以保存到磁盘并从磁盘中检索的格式,因此它基本上浪费在二进制文件上,可以轻松直接保存而无需任何修改。

So, to sum that all up, while you totally can save large data blobs to a database, over time, it'll potentially result in performance hits and file size bloat that you could have otherwise avoided. These sorts of databases are designed to help transform small bits of data to a format that can be saved to and retrieved from disk, so it's essentially wasted on binary files that could easily be directly saved without any modification.

将大型二进制数据简单地存储在磁盘上通常更简单,更简洁,更高效,并且只需在数据库中存储文件名引用即可。 :)

It's usually much easier, cleaner and more efficient to simply store your large binary data on disk, and simply store a file name reference to them inside the database. :)

这篇关于为什么建议将图像存储在磁盘而不是Realm中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆