您如何最小化或压缩Core Data sqlite文件大小?

时间:2011-10-21 23:29:01

标签: iphone objective-c core-data

我有一个215MB的csv文件,我已经解析并存储在我自己的自定义对象中的核心数据中。问题是我的核心数据sqlite文件大约是260MB。 csv文件包含我城市交通系统(公交车站,时间,路线等)的大约450万行数据。

我尝试修改属性,以便表示停止时间的字符串数组存储为NSData文件,但由于某种原因,文件大小仍然保持在260MB左右。

我无法发送此尺寸的应用。我怀疑有人会想要下载一个260MB的应用程序,即使这意味着他们有整个城市的运输时间表。

有没有办法压缩或最小化使用的存储空间(即使它意味着不使用核心数据,我愿意听取建议)?

编辑:我只是想立即提供更新,因为我一直难以置信地盯着文件大小。通过一些涉及字符串,索引和数据库规范化的巧妙操作,我已经设法在压缩时将大小减小到6.5MB或2.6MB。 Core Data中存储的大约105,000个对象包含城市交通系统的全部详细信息。我现在几乎要流泪了D':

3 个答案:

答案 0 :(得分:8)

除非您的原始CSV以非常愚蠢的方式编码,否则无论您压缩多少,它的大小似乎都不会低于100M。对于应用来说,这仍然非常大。解决方案是将您的数据移动到Web服务。您可能想要下载和缓存重要部分,但如果您正在谈论数百万条记录,那么从服务器获取最好。此外,我不得不相信,交通系统不时会发生变化,每次进行一次停止调整时,必须升级10多MB的应用程序才会令人沮丧。


我已经说过,但实际上你可以考虑一些事情:

  • 将布尔值移动到一些字段中。您可以将64个布尔值放入NSUInteger。 (如果你只需要8位,就不要使用完整的64位整数。尽可能存储最小的东西。)
  • 压缩存储时间的方式。一天只有1440分钟。您可以将其存储在2个字节中。过境时间一般不到第二;他们不需要CGFloat。
  • 星期几和日期可以同样压缩。
  • 显然你应该规范化任何字符串。在CSV上查看多行重复字符串值。
  • 我一般会建议使用原始sqlite而不是核心数据来解决这类问题。核心数据更多地是关于对象持久性而不是原始数据存储。事实上,你看到对于这个问题,这个问题并不是一个很好的方向,因此你看到这个问题不是一个很好的方向。
  • 如果您想要更紧凑,并且不需要非常好的搜索功能,您可以创建打包数据blob。我曾经在内存非常紧张的手机交换机上这样做。你创建一个位字段结构,为一个变量分配5位,为另一个变量分配7位,等等。有了这些,并且有些时候将它们混合起来,使它们在字边界上正确排列,你可以变得非常紧张。

由于您最关心初始下载大小,并且可能愿意稍后扩展数据以便更快地访问,因此您可以考虑针对特定于域的压缩。例如,在上面的讨论中,我提到了如何在一段时间内减少2个字节。在许多情况下,你可以通过将时间存储为自上次以来的增量分钟来减少1个字节(因为如果它们是公共汽车和火车时刻表,大多数时间将总是以相当小的步数增加)。放弃数据库,您可以创建一个非常紧密编码的数据文件,您可以在首次启动时将其提取到数据库中。

您还可以使用特定于域的知识将字符串编码为较小的标记。如果我编码纽约地铁系统,我会注意到一些字符串显示很多,如“大道”,“道路”,“街道”,“东方”等。我可能将那些编码为不可打印的ASCII像^ A,^ R,^ S,^ E等我可能将“138 Street”编码为两个字节(0x8A13)。这当然是基于我的知识,è(0x8a)从未出现在纽约地铁站。这不是一般解决方案(在巴黎它可能是一个问题),但它可以用于高度压缩您特别了解的数据。在像华盛顿特区这样的城市,我相信他们编号最高的街道是第38街,然后是4值方向。因此,您可以将其编码为两个字节,首先是“编号街道”令牌,然后是一个位字段,其中象限为2位,街道号为6位。这种想法可能会大大缩小您的数据量。

答案 1 :(得分:0)

您可以执行一些数据库规范化。

查找可能多余的内容或存储在多行中的相同值。您可能需要重构数据库,以便将这些重复值(如果有)存储在单独的表中,然后通过id's从原始行引用。

答案 2 :(得分:0)

压缩sqlite文件有多大?如果它是令人满意的小,最简单的方法是将其压缩,然后将其解压缩到NSCachesDirectory。